使用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)问题是一个著名的线程同步问题.它描述的是:有一群生产者线程在生产产品,并将这些产品提供给消费者线程去消费. 为使生产者与消费者之间能够并发执行,在两 ...
随机推荐
- 引水工程 Kruskal + Prim
Kruskal题解 : 以案例输入为例 有五个缺水地区 , 这个个缺水地区之间建立联系的费用已经给出 并且之间水库的费用也已经给出 , 自己水库也已看为 是另一个 点 , 这样就有了 6 个点 , 这 ...
- what is success?
什么是成功?这是个老话题了.然而每个人对成功的认识却也不同.记得央视主持人王志说过成功是相对的,每个人都有自己的成功标准.有的人认为有钱.有房.有车.有女人,就是成功.有的人则认为成功是你做了一件你想 ...
- 启用禁用USB接口
一个小工具,功能有启用禁用外网.USB接口,可由服务端socket长链接进行操控客户端从而达到实现前边的这些功能,这里贴上核心代码,先给上启用禁用USB接口吧,这个方法可随时启用禁用,之前用过一个改u ...
- 深入理解async和await的作用及各种适用场景和用法
https://www.cnblogs.com/yaopengfei/archive/2018/07/02/9249390.html https://www.cnblogs.com/xianyudot ...
- drupal-使用hook_preprocess_field在paragraph的accordion中添加自定义数据
描述:我的accordion类型原先只有两个字段,分别是title和content.显示在页面上会默认隐藏其内容,点击“+”会显示内容.然而现在有一个新需求,就是加一个开关使编辑内容者可以选择默认“展 ...
- DB2使用收集
db2命令收集 创建带分区的表: create table table_name( )in table_space index in index_space partition by range(c ...
- JS——缓动动画
核心思想: (1)相对于匀速移动,盒子每次移动的步长都是变化的,公式:盒子位置=盒子本身位置+(目标位置-盒子本身位置)/10 (2)在盒子位置与目标距离小于10px时,其步长必然是小数,又由于off ...
- Centos6.7安装Cacti教程
Centos6.7安装Cacti教程# link:http://docs.cacti.net/plugins/ blog地址:http://www.cnblogs.com/caoguo 一.基本环境安 ...
- HDU_1023_Train Problem II_卡特兰数
Train Problem II Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- api 签名算法
<?php define('token', 'tokensecret'); // 定义私钥token /** * 哈希验证签名 */ function hmacSign($array, $tok ...