使用Win32 API实现生产者消费者线程同步
使用win32 API创建线程,创建信号量用于线程的同步
创建信号量
语法例如以下
HANDLE semophore;
semophore = CreateSemaphore(lpSemaphoreAttributes, lInitialCount, lMaximumCount, lpName);
CreateSemophore函数的原型例如以下:
HANDLE WINAPI CreateSemaphore(
_In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,//属性
_In_ LONG lInitialCount,//初始值
_In_ LONG lMaximumCount,//最大值
_In_opt_ LPCTSTR lpName//信号量对象的名字
);
函数返回一个指向信号量对象的句柄,是一个HANDLE对象
wait操作和signal操作
使用结构通常是这种
while(true){
WaitForSingleObject(semophore,INFINITE);//wait操作
//临界区
ReleaseSemaphore(semophore,1,NULL);//signal操作
}
两个函数的原型例如以下:
DWORD WaitForSingleObject(
HANDLE hHandle,//句柄。能够指向信号量或者线程
DWORD dwMilliseconds//等待的毫秒数
);
BOOL ReleaseSemaphore(
HANDLE hSemaphore,//句柄,指向信号量
LONG lReleaseCount,//给信号量添加值,通常是1
LPLONG lpPreviousCount//保存信号量之前的值的变量的指针
);
创建线程
HANDLE producer;
//PRODUCER 线程运行这个函数
//pro_id 线程id
producer = CreateThread(NULL, 0, PRODUCER, NULL, 0, &pro_id);//创建线程
函数原型
HANDLE WINAPI CreateThread(
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,//指向线程属性结构体的指针
_In_ SIZE_T dwStackSize,//栈的初始化大小,0表示使用默认的大小
_In_ LPTHREAD_START_ROUTINE lpStartAddress,//起始地址,也就是线程函数的指针
_In_opt_ LPVOID lpParameter,//线程函数參数的指针
_In_ DWORD dwCreationFlags,//控制创建的标志位,0表示线程创建后马上运行,CREATE_SUSPENDED表示新建为suspended状态,直到 ResumeThread 被调用时才运行。STACK_SIZE_PARAM_IS_A_RESERVATION,由dwStackSize 參数指定初始的保留栈的大小。不指定的话,dwStackSize指定提交的大小
_Out_opt_ LPDWORD lpThreadId//线程id的指针
);
生产者消费者线程同步代码例如以下
#include<Windows.h>
#include<iostream> #define QUEUE_LENGTH 10 //缓冲区长度 HANDLE full_sem; //满信号量
HANDLE empty_sem; //空信号量 struct Msg
{
int i;
};//消息结构 Msg MsgQueue[QUEUE_LENGTH]; //缓冲区
int head = 0;//队列头
int tail = 0;//队列尾 DWORD WINAPI CONSUMER(LPVOID lpParameter){//消费者线程
for (int i = 0;;i++){ WaitForSingleObject(full_sem, INFINITE);//wait操作
//WaitForSingleObject(mutex, INFINITE);//多个消费者须要加相互排斥信号量
int val = MsgQueue[head].i;
head = (head + 1) % QUEUE_LENGTH;
//ReleaseSemaphore(mutex, 1, NULL);//signal操作
std::cout << "CONSUMER : "<<val<< std::endl; ReleaseSemaphore(empty_sem, 1, NULL);//signal操作
} return 0;
} DWORD WINAPI PRODUCER(LPVOID lpParameter){//生产者线程
for (int i = 0;; i++){
WaitForSingleObject(empty_sem, INFINITE);
//WaitForSingleObject(mutex, INFINITE);//多个生产者须要加相互排斥信号量
MsgQueue[tail].i = i;
tail=(tail+1) % QUEUE_LENGTH;
//ReleaseSemaphore(mutex, 1, NULL);
std::cout << "PRODUCER : " <<i<< std::endl; ReleaseSemaphore(full_sem, 1, NULL);
} return 0;
} int main(){ full_sem = CreateSemaphore(NULL, 0, QUEUE_LENGTH, NULL);//创建信号量 初始值为0,最大值为QUEUE_LENGTH
empty_sem = CreateSemaphore(NULL,QUEUE_LENGTH,QUEUE_LENGTH,NULL); DWORD pro_id;//pid
DWORD con_id; HANDLE producer = CreateThread(NULL, 0, PRODUCER, NULL, 0, &pro_id);//创建线程
//Sleep(1000);//展示堵塞 HANDLE consumer = CreateThread(NULL, 0, CONSUMER, NULL, 0, &con_id); WaitForSingleObject(producer, INFINITE);
WaitForSingleObject(consumer, INFINITE);//等待线程运行完成 CloseHandle(producer);
CloseHandle(consumer);//关闭内核对象 }
使用Win32 API实现生产者消费者线程同步的更多相关文章
- Hadoop生态圈-Kafka的旧API实现生产者-消费者
Hadoop生态圈-Kafka的旧API实现生产者-消费者 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.旧API实现生产者-消费者 1>.开启kafka集群 [yinz ...
- Java基础 线程的通信的三个方法/ 交替数数线程 / 生产者&消费者线程问题
线程通讯笔记: /** 线程通信 三个方法: * wait(): 调用该方法 是该调用的方法的线程释放共享资源的锁,进入等待状态,直至被唤醒 * notify() : 可以唤醒队列中的第一个等待同一共 ...
- [C++] socket - 6 [API互斥事件对象实现线程同步]
/*API互斥事件对象实现线程同步*/ #include<windows.h> #include<stdio.h> DWORD WINAPI myfun1(LPVOID lpP ...
- [C++] socket - 5 [API事件对象实现线程同步]
/*API事件对象实现线程同步*/ #include<windows.h> #include<stdio.h> DWORD WINAPI myfun1(LPVOID lpPar ...
- Hadoop生态圈-Kafka的新API实现生产者-消费者
Hadoop生态圈-Kafka的新API实现生产者-消费者 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- wait和notify实现的生产者消费者线程交互
public class ProductTest { public static void main(String args[]) { Repertory repertory=new Repertor ...
- win32多线程 (二)线程同步之临界区 (critical sections)
所谓critical sections 意指一小块“用来处理一份被共享之资源”的程序代码.你可能必须在程序的许多地方处理这一块可共享的资源.所有这些程序代码可以被同一个critical sectio ...
- linux 信号量sem实现 生产者—消费者(线程间通信)
#include<pthread.h> #include<stdlib.h> #include<stdio.h> #include<unistd.h> ...
- 经典线程同步问题(生产者&消费者)--Java实现
生产者-消费者(producer-consumer)问题是一个著名的线程同步问题.它描述的是:有一群生产者线程在生产产品,并将这些产品提供给消费者线程去消费. 为使生产者与消费者之间能够并发执行,在两 ...
随机推荐
- hcode视频教程中心(学习h5和hbuilder等)
网站: http://www.hcoder.net/course
- MVC系列学习(八)-分布视图
1.本次学习实例 1.1.建议:为了尽可能让项目简单,就新建一个空的mvc项目,同时添加任何视图不用模板页 1.2注意:在添加LoginPart的分部视图时,要记得沟一个沟 2.项目代码,如下 总共三 ...
- zblog插件增加后台导航栏的方法
有时我们经常需要对插件进行设置,但是又不能让用户去做这些,那么下面的方法将会给插件增加在后台导航栏显示的功能 首先打开对应插件的文件夹,找到对应插件的 include.php 文件 将下面的代码粘 ...
- MonoBehaviour简述
Unity中的脚本都是继承自MonoBehaviour. 一.基础函数: 创建脚本就默认的update.start方法:(这些官方的文档都是有的) Start:Update函数第一次运行前调用,一般用 ...
- vue iView 打包后 字体图标不显示
问题描述: 今天webpack打包后发现iView 字体图标不显示 解决方案: build/webpack.prod.conf.js 这个文件里面 module: { rules: utils.sty ...
- [Windows Server 2008] 查看ASP详细错误信息方法
★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com ★ 护卫神·V课堂是护卫神旗下专业提供服务器教学视频的网站,每周更新视频. ★ 本节我们将带领大家:查看IIS下 ...
- 7、scala面向对象编程之类
1. 定义一个简单的类 2.getter与setter 3.自定义getter与setter方法 4.仅暴露field的getter方法 5.private[this]的使用 6.Java风格的ge ...
- for mxl path
废话不多说,直接上例子 简单明了 create table tb_class ( classId int , className ) ) go ,'一班') ,'二班') ,'三班') go crea ...
- centOS安装python3 以及解决 导入ssl包出错的问题
参考: https://www.cnblogs.com/mqxs/p/9103031.html https://www.cnblogs.com/cerutodog/p/9908574.html 确认环 ...
- (5.2.1)配置服务器参数——即时文件初始化(IFI)
关键词:零填充,即时文件初始化 转自:https://www.cnblogs.com/gaizai/p/3516905.html 概念: 所有新申请的空间,sql server都要以0来填充完磁盘文件 ...