线程间同步和通信,event semaphore mailbox

  • 1. 概述
  • 2. 事件event
  • 3. wait_order()
  • 4. 旗语(semaphore)
  • 5. semaphore::get();
  • 6. semaphore::try_get()
  • 7. 信箱mailbox
    • 7.1. 信箱的内建方法
    • 7.2. mailbox::new()
    • 7.3. mailbox::num()
    • 7.4. 参数化信箱

1. 概述

  • 测试平台中的所有线程都需要同步并交换数据
  • 一个线程等待另外一个,例如验证环境需要等待所有激励结束、比较结束才可以结束仿真
  • 比如检测器需要将将测到的数据发送至比较器,比较器又需要从不同的缓存获取数据进行比较

2. 事件event

  • 可以通过event来声明一个命名event变量,并且去触发它
  • 这个命名event可以用来控制进程的执行
  • 可以通过->来触发事件
  • 其他等待该事件的进程可以通过@操作符或者wait()来检查event触发状态来完成
`timescale 1ns/1ns
module tb7;event e1, e2, e3;task automatic wait_event(event e, string name);$display("@%t start waiting event %s", $time, name);@e;$display("@%t finish waiting event %s", $time, name);endtaskinitial beginforkwait_event(e1, "e1");wait_event(e2, "e2");wait_event(e3, "e3");joinendinitial beginforkbegin #10ns -> e1; endbegin #20ns -> e2; endbegin #30ns -> e3; endjoinendendmodule

module tb8;bit e1, e2, e3;task automatic wait_event(ref bit e, input string name);$display("@%t start waiting event %s", $time, name);@e;$display("@%t finish waiting event %s", $time, name);endtaskinitial beginforkwait_event(e1, "e1");wait_event(e2, "e2");wait_event(e3, "e3");joinendinitial begin$display("before fork, e1 = %x", e1);forkbegin #10ns e1 = !e1; endbegin #20ns e2 = !e2; endbegin #30ns e3 = !e3; endjoin$display("after fork, e1 = %x", e1);endendmodule

3. wait_order()

  • wait_order可以使得进程保持等待,直到在参数列表中的事件event按照顺序从左到右依次完成
  • 如果参数列中的事件被触发但是没有按照要求的顺序,那么使得等待操作失败
wait_order(a, b, c);wait_order(a, b, c) else $display("Error: events out of order");bit success;
wait_order(a, b, c) success = 1; esle success = 0;

【Q】下面关于event的说法哪些是正确的?
A: event之间也可以拷贝
B: 被拷贝的event与拷贝的event指向同一个event
C: 如果event先发生,再@event,不会被阻塞
D: 如果event先发生,再wait(event.triggered),不会被阻塞

【An】
event之间做拷贝,拷贝的是句柄
@是边沿触发
wait是电平触发

4. 旗语(semaphore)

  • 旗语从概念上讲,是一个容器
  • 在创建旗语的时候,会为其分配固定的钥匙数量
  • 使用旗语的进程必须先获得其钥匙,才可以继续执行
  • 旗语的钥匙数量可以有很多个,等待旗语钥匙的进程也可同时有很多个
  • 旗语通常用于互斥,对共享资源的访问控制,以及基本的同步
  • 目的是为了保护共享资源,规定访问资源的钥匙·1

  • 创建旗语,并为其分配钥匙,
    semaphore sm;
    sm = new();
  • 创建一个具有固定钥匙数量的旗语,
    new (N = 0)
  • 从旗语那里获取一个或多个钥匙(阻塞型),
    get (N = 1)
  • 将一个或多个钥匙返回到旗语中,
    put (N = 1)
  • 尝试获取一个或多个钥匙而不会阻塞(非阻塞型),
    try_get (N = 1)
module tb9;semaphore mem_acc_key;int unsigned mem[int unsigned];task automatic write_mem(int unsigned addr, int unsigned data);mem_acc_key.get();#1ns;mem[addr] = data;mem_acc_key.put();endtasktask automatic read_mem(int unsigned addr, output int unsigned data);mem_acc_key.get();#1ns;if(mem.exists(addr))data = mem[addr];elsedata = 'x;mem_acc_key.put();endtaskinitial beginint unsigned data = 100;mem_acc_key = new(1);forever beginforkbegin#10ns;write_mem('h10, data+100);$display("@%t write with data %d", $time, data);endbegin#10ns;read_mem('h10, data);$display("@%t read  with data %d", $time, data);endjoinendend
endmodule

5. semaphore::get();

  • get()方法用于从旗语中获取指定数量的钥匙
  • get()原型,
    task get(int ketCount = 1);
  • keyCount指定从旗语获取所需的钥匙数,默认值为1
  • 如果指定数量的钥匙可用,则该方法返回并继续执行
  • 如果指定数量的钥匙不足,进程将阻塞,知道钥匙数目充足
  • 旗语的等待队列是先进先出(FIFO),即先排队等待旗语的将优先得到钥匙

6. semaphore::try_get()

  • try_get()方法用于从信号量中获取指定数量的钥匙,但不会被阻塞
  • try_get()原型,
    function int try_get(int keyCount = 1);
  • keyCount指定从旗语处获取所需的钥匙数目,默认值为1
  • 如果指定数量的钥匙可用,则该方法返回正数并继续执行
  • 如果指定数量的钥匙不足,则该方法返回0

7. 信箱mailbox

  • 信箱mailbox可以使得进程之间的信息的以交换,数据可以由一个进程写入信箱,再又另外一个进程获得
  • 信箱在创建时可以限制其容量,或者不限制
  • 当 信箱容量写满时,后续再写入的动作会被挂起,直到信箱的数据从中读取,使得信箱有空间以后才可以继续写入
  • 不限制容量的信箱则不会被挂起写入信箱的动作

7.1. 信箱的内建方法

  • 创建信箱:new()
  • 将信息写入信箱:put()
  • 试着写入信箱但不会阻塞:try_put()
  • 获取信息:get()同时会取出数据,peek()不会取出数据
  • 试着从信箱中取出数据但不会阻塞:try_get() / try_peek()
  • 获取信箱信息的数据:num()

7.2. mailbox::new()

  • 可以在创建信箱的时候限定或者不限定其大小,
    function new(int bound = 0);
  • 默认情况下,如果不传入参数,bound默认值为0,表示不限定信箱大小,如果传入的数值大于0,那么表示信箱的最大容量
  • bound应为正数,如果为负数的话,系统会提示警告和出现无预期的行为

7.3. mailbox::num()

  • num()会但会信箱目前的消息数目
  • 可以结合num()和get()或者put(),防止get() / put()方法在信箱为空或者为满的时候被阻塞
module tb10;mailbox #(int) mb;initial beginint data;mb = new(8);forever begincase($urandom_range(0, 1))0: beginif(mb.num() < 8) begindata = $urandom_range(0, 10);mb.put(data);$display("mb put data %0d", data);endend1: beginif(mb.num() > 0) beginmb.get(data);$display("mb get data %0d", data);endendendcase#1ns;endend
endmodule

7.4. 参数化信箱

  • 默认的信箱,在没有指定存储类型的情况下,可以存储任何类型的数据(程序也可能会为此受伤)
  • 为了避免运行时错误和类型不匹配,建议在声明信箱的时候为其指定存储类型

【Q】关于信箱的说法,正确的是?
A: 可以指定信箱存储的数据类型
B: 可以不限制信箱的容量大小
C: 在信箱写满时,继续写入,数据会溢出丢失
D: 在信箱为空时,调用get()方法将返回数值0

【An】
信箱写满继续写会等待
信箱为空,用get()会阻塞,用try_get()返回0

线程间同步和通信,event semaphore mailbox相关推荐

  1. IOT-OS之RT-Thread(六)--- 线程间同步与线程间通信

    文章目录 一.IPC对象管理 1.1 IPC对象控制块 1.2 IPC对象接口函数 二.线程间同步对象管理 2.1 信号量对象管理 2.2 互斥量对象管理 2.3 事件集对象管理 三.线程间通信对象管 ...

  2. Linux多线程编程---线程间同步(互斥锁、条件变量、信号量和读写锁)

    本篇博文转自http://zhangxiaoya.github.io/2015/05/15/multi-thread-of-c-program-language-on-linux/ Linux下提供了 ...

  3. 【JUC并发编程04】线程间定制化通信(单标志法存在的问题)

    文章目录 4 线程间定制化通信 案例实现 该案例需要注意 4 线程间定制化通信 案例实现 案列:启动三个线程,按照如下要求: AA打印5此,BB打印10次,CC打印15次,一共进行10轮 具体思路: ...

  4. LinuxC高级编程——线程间同步

    LinuxC高级编程--线程间同步 宗旨:技术的学习是有限的,分享的精神是无限的. 1. 互斥锁mutex 多个线程同时访问共享数据时可能会冲突.对于多线程的程序,访问冲突的问题是很普遍的,解决的办法 ...

  5. (28)System Verilog进程间同步(事件event)

    (28)System Verilog进程间同步(事件event) 1.1 目录 1)目录 2)FPGA简介 3)System Verilog简介 4)System Verilog进程间同步(事件eve ...

  6. 进程间通信 和 线程间同步

    以前经常搞混,所以记录下来. 进程间通信主要是指多个进程间的数据交互. 而线程间同步主要指维护多个线程之间数据准确.一致性. 一.进程间通信主要有以下几种方式: 管道(pipe):管道是一种半双工的通 ...

  7. 操作系统:进程间通信与线程间同步

    进程线程通信方式之间的差异 每个进程有自己的地址空间.两个进程中的地址即使值相同,实际指向的位置也不同.进程间通信一般通过操作系统的公共区进行.   同一进程中的线程因属同一地址空间,可直接通信. 不 ...

  8. 线程间同步的几种方法--互斥锁,条件变量,信号量,读写锁

    一.互斥锁(mutex) 锁机制是同一时刻只允许一个线程执行一个关键部分的代码. 1 . 初始化锁 int pthread_mutex_init(pthread_mutex_t *mutex,cons ...

  9. 面试官 | 线程间是如何通信的?

    作者 | wingjay 来源 | wingjay.com 正常情况下,每个线程独立完成自己的任务就结束了,但某些特殊情况下,我们需要多个线程来共同完成某项任务,这时就涉及到了线程间通信了. 本文涉及 ...

最新文章

  1. 知乎:什么时候你是产品经理,而不是产品助理?
  2. python 购物车分析_python 简易购物车程序解析
  3. JAVA实现在面板中添加图表_Java 创建PowerPoint图表并为其添加趋势线
  4. 【转】C#字节数组_字符串相互转换
  5. python syslog 接口_python接口测试之日志功能
  6. 2020年7大技术趋势
  7. java并发临界资源管理
  8. Linux/Ubuntu 单机配置Hbase
  9. python makefile
  10. 管理者要会讲的六十八个故事
  11. 数据可视化大屏案例系列 1
  12. 整理收纳的概念和意义
  13. 小米洪锋:跟7000万MIUI用户谈谈
  14. CSDN线上竞赛第52期题解
  15. http状态码查询表(转载)
  16. 如何去除ie的select下拉框箭头图标
  17. 教你如何使用WinCE CAB Manager制作PPC绿色软件
  18. 国内oschina Maven公共仓库
  19. 对数函数定义域和值域_对数函数的定义域,值域是怎么求的
  20. NXP SPIFI(QSPI)应用详解与程序固件分散加载

热门文章

  1. 怎么还原计算机主机名称,台式电脑怎么恢复出厂设置
  2. ABI Research产业研究:ZiFiSense如何革新物流货物及运输包装追踪
  3. 大龄80后我们何时告别单身?_转
  4. 简述 jvm 原理与工作流程
  5. 东北林业大学Acm培训大一(三)(暴力枚举)
  6. 新开blog~~ 哈哈
  7. JavaScript 面试题(二十)延时器
  8. 项目二:LED点阵实验
  9. python编写代码实现文件的拷贝功能_python从一个文件夹自动拷贝文件到目标文件夹的代码...
  10. PCL——基于惯性矩与偏心率的描述子进行包围盒提取