• SV--线程(semaphore)


    2 semaphore

    2.1概述

    semaphore可以实现对同一资源的访问控制。

    semaphore有三种基本操作。new()方法可以创建一个带单个或多个钥匙的semaphore, 使用get()可以获取一个或者多个钥匙,而put()可以返回一个或者多个钥匙。


    如果试图获取一个semaphore而希望不被阻塞,可以使用try_get()函数,它返回1表示有足够多的钥匙,而返回0则表示钥匙不够。

    2.2实例演练 

    1. program automatic test(bus_ifc.TB bus);
    2. semaphore sem; //创建一个semaphore
    3. initial begin
    4. sem = new(l); //分配一个钥匙
    5. fork
    6. sequencer(); / /产生两个总线事务线程
    7. sequencer();
    8. join
    9. end
    10. task sequencer;
    11. repeat($urandom%10) //随机等待0-9个周期
    12. @bus.cb;
    13. sendTrans(); //执行总线事务
    14. endtask
    15. task sendTrans;
    16. sem.get(1); //获取总线钥匙
    17. @bus.cb; //把信号驱动到总线上
    18. bus.cb.addr <= t.addr;
    19. ...
    20. sem.put(l); //处理完成时把钥匙返回
    21. endtask
    22. endprogram

    控制共享资源的原因在于,如果不对其访问做控制,可能会出现多个线程对同一资源的访问,进而导致不可预期的数据损坏和线程的异常,这种现象称之为“线程不安全”。

    1. class car;
    2. semaphore key;
    3. function new();
    4. key = new(l);
    5. endfunction
    6. task get_on(string p);
    7. $display("%s is waiting for the key", p);
    8. key.get();
    9. #lns;
    10. $display ("%s got on the car", p);
    11. endtask
    12. task get_off(string p);
    13. $display("%s got off the car", p);
    14. key.put();
    15. #lns;
    16. $display ("%s returned the key", p);
    17. endtask
    18. endclass
    19. module family;
    20. car byd = new();
    21. string pl = "husband";
    22. string p2 = "wife";
    23. initial begin
    24. fork
    25. begin//丈夫开车
    26. byd.get_on(pl);
    27. byd.get_off(pl);
    28. end
    29. begin//妻子开车
    30. byd.get_on(p2);
    31. byd.get_off(p2);
    32. end
    33. join
    34. end
    35. endmodule

    # husband is waiting for the key

    # wife is waiting for the key 
    # husband got on the car 
    # husband got off the car 
    # husband returned the key 
    # wife got on the car 
    # wife got off the car 
    # wife returned the key 

    &1:一开始在拿到这辆车的时候,只有一把钥匙,而丈夫和妻子如果都想开车的话,也得遵循先到先得的原则。所以,当丈夫和妻子同时都想用车的时候,一把钥匙只能交给他们中的一位,另外一位则需要等待,直到那把钥匙归还之后才可以使用。

    &2:从上面的输出结果来看,也是能够看出来,虽然丈夫和妻子在同一时间想开这辆车,然而也只能允许一位家庭成员来驾驶。直到丈夫从车上下来,归还了钥匙以后,妻子才可以上车。

    &3:这个生动的例子解释了semaphore对于控制访问共享资源的帮助,从上semaphore key的使用来看,key在使用前必须要做初始化,即要告诉用户它原生自带几把钥匙。
    &4:从例子来看,它只有1把钥匙,而丈夫和妻子在等待和归还钥匙时,没有在semaphore ::get()/put()函数中传递参数,即默认他们等待和归还的钥匙数量是1。semaphore可以被初始化为多个钥匙,也可以支持每次支取和归还多把钥匙用来控制资源访问。

    &5:那么如果上面的semaphore, 用自定义的类来实现,该怎么做呢?

     

    1. class carkeep;
    2. int key= 1;
    3. string q[$];
    4. string user;
    5. task keep_car();
    6. fork
    7. forever begin//管理钥匙和分发
    8. wait(q. size() != 0 && key != 0);
    9. user = q.pop_front();
    10. key--;
    11. end
    12. join_none;
    13. endtask
    14. task get_key(string p); //拿钥匙
    15. q.push_back(p);
    16. wait(user= p);
    17. endtask
    18. task put_key(string p); //还钥匙
    19. if(user = p) begin
    20. user= "none";
    21. key++;
    22. end
    23. endtask
    24. endclass
    25. class car;
    26. carkeep keep;
    27. function new();
    28. keep= new();
    29. endfunction
    30. task drive() ;
    31. keep.keep_car();
    32. endtask
    33. task get_on (string p);
    34. $display("%s is waiting for the key", p);
    35. keep.get_key(p);
    36. #lns;
    37. $display("%s got on the car", p) ;
    38. endtask
    39. task get_off(string p);
    40. $display("%s got off the car", p) ;
    41. keep.put_key(p);
    42. #lns;
    43. $display("%s returned the key", p);
    44. endtask
    45. endclass
    46. module family;
    47. car byd = new();
    48. string pl = "husband";
    49. string p2 = "wife";
    50. initial begin
    51. fork
    52. begin//丈夫开车
    53. byd.get_on(pl);
    54. byd.get_off(pl);
    55. end
    56. begin//妻子开车
    57. byd.get_on(p2);
    58. byd.get_off(p2);
    59. end
    60. join
    61. end
    62. endmodule

    # husband is waiting for the key

    # wife is waiting for the key 
    # husband got on the car 
    # husband got off the car 
    # husband returned the key 
    # wife got on the car 
    # wife got off the car 
    # wife returned the key 

    这对夫妻除了有一辆车之外,还添加了一个智能车管家carkeep,这个管家的作用使得夫妻不在因为车到底该给谁开而惹得让人不开心,他会公平地保管,分发和回收钥匙。

     

  • 相关阅读:
    【云原生】FlexCloud 云数据转HTTP开发接口操作
    Leetcode 1670. Design Front Middle Back Queue
    Linux多线程C++版(七) 线程互斥方式-----读写锁
    HTML基础-表单标签,button按钮,select下拉菜单
    java毕业设计家教管理系统(附源码、数据库)
    BLE学习(1):蓝牙协议栈的介绍
    侦查帮派问题
    Java8 函数式编程【基础篇】
    BatchNormalization:解决神经网络中的内部协变量偏移问题
    虹科分享 | 简单实用的CANopen介绍,看完你就明白了(1)
  • 原文地址:https://blog.csdn.net/weixin_45680021/article/details/126067637