API 练习 第一篇
练习API
CreateSemaphore
CreateEvent
ReleaseSemap
WaitForSingleObject
CloseHandle
InitializeCriticalSection
EnterCriticalSection
LeaveCriticalSection
DeleteCriticalSection
例子:读者与写者,有一位写者与三位读者,要求当三位读者都读操作完成时写者才能开始写操作,写的过程中不能有任何读者进行读操作。用信号量解决问题
代码如下:
- // ReaderAndWriter.cpp : 定义控制台应用程序的入口点。
//- #include "stdafx.h"
#include <Windows.h>
#include <stdio.h>- int gBook = 0;
CRITICAL_SECTION cs;- //线程句柄
HANDLE hThread[4];- //线程体
DWORD WINAPI threadWrite(void *param);
DWORD WINAPI threadRead1(void *param);
DWORD WINAPI threadRead2(void *param);
DWORD WINAPI threadRead3(void *param);- //信号量句柄
HANDLE hWriteSM;
HANDLE hRead1SM;
HANDLE hRead2SM;
HANDLE hRead3SM;- //线程退出事件
HANDLE hEventWriteExit;
HANDLE hEventRead1Exit;
HANDLE hEventRead2Exit;
HANDLE hEventRead3Exit;- /********************************************
程序说明:
一个写线程与三个读线程共同访问gBook,要求当三
个读线程都读完后,写线程才开始写gBook。
主线程等待6秒后通知退出事件,清理资源,结束程序
*********************************************/
- int _tmain(int argc, _TCHAR* argv[])
- {
- //初始化临界区
- InitializeCriticalSection(&cs);
- //线程退出事件
- hEventWriteExit = CreateEvent(NULL, false, false, NULL);
- hEventRead1Exit = CreateEvent(NULL, false, false, NULL);
- hEventRead2Exit = CreateEvent(NULL, false, false, NULL);
- hEventRead3Exit = CreateEvent(NULL, false, false, NULL);
- //创建读者写者信号量
- hWriteSM = CreateSemaphore(NULL, 0, 3, NULL);//写信号量初始为unsignal ,可知先进行的是读操作
- hRead1SM = CreateSemaphore(NULL, 1, 1, NULL);//读信号量初始为signal,
- hRead2SM = CreateSemaphore(NULL, 1, 1, NULL);//读信号量初始为signal,
- hRead3SM = CreateSemaphore(NULL, 1, 1, NULL);//读信号量初始为signal,
- //创建四个线程
- hThread[0] = CreateThread(NULL, 0, threadWrite, NULL, 0, NULL);
- hThread[1] = CreateThread(NULL, 0, threadRead1, NULL, 0, NULL);
- hThread[2] = CreateThread(NULL, 0, threadRead2, NULL, 0, NULL);
- hThread[3] = CreateThread(NULL, 0, threadRead3, NULL, 0, NULL);
- //等待线程执行6秒
- Sleep(1000 * 6);
- //发出通知线程结束事件
- SetEvent(hEventWriteExit);
- SetEvent(hEventRead1Exit);
- SetEvent(hEventRead2Exit);
- SetEvent(hEventRead3Exit);
- //等待四个线程都结束
- WaitForMultipleObjects(4, hThread, true, INFINITE);
- //关闭句柄,清理资源
- CloseHandle(hEventWriteExit);
- CloseHandle(hEventRead1Exit);
- CloseHandle(hEventRead2Exit);
- CloseHandle(hEventRead3Exit);
- CloseHandle(hWriteSM);
- CloseHandle(hRead1SM);
- CloseHandle(hRead2SM);
- CloseHandle(hRead3SM);
- for (int i = 0; i < 4; i ++)
- CloseHandle(hThread[i]);
- DeleteCriticalSection(&cs);
- printf("\t main end \n");
- return 0;
- }
- DWORD WINAPI threadWrite(void *param)
- {
- while(1)
- {
- DWORD dwWait = WaitForSingleObject(hEventWriteExit, 10);
- if (WAIT_TIMEOUT != dwWait)
- {
- //接收到退出事件后先把资源归还,避免造成死锁
- ReleaseSemaphore(hRead1SM, 1, NULL);
- ReleaseSemaphore(hRead2SM, 1, NULL);
- ReleaseSemaphore(hRead3SM, 1, NULL);
- break;
- }
- WaitForSingleObject(hWriteSM, INFINITE);
- WaitForSingleObject(hWriteSM, INFINITE);
- WaitForSingleObject(hWriteSM, INFINITE);
- EnterCriticalSection(&cs);
- gBook ++;
- printf(" \n Write Process end:%d \n", gBook);
- LeaveCriticalSection(&cs);
- ReleaseSemaphore(hRead1SM, 1, NULL);
- ReleaseSemaphore(hRead2SM, 1, NULL);
- ReleaseSemaphore(hRead3SM, 1, NULL);
- Sleep(1000);
- }
- printf("\n******************writer Terminate \n");
- return 0;
- }
- DWORD WINAPI threadRead1(void *param)
- {
- while(1)
- {
- DWORD dwWait = WaitForSingleObject(hEventRead1Exit, 10);
- if (WAIT_TIMEOUT != dwWait)
- {
- //接收到退出事件后先把资源归还,避免造成死锁
- ReleaseSemaphore(hWriteSM, 1, NULL);
- break;
- }
- WaitForSingleObject(hRead1SM, INFINITE);
- EnterCriticalSection(&cs);
- printf("reader1 process end %d \t", gBook);
- LeaveCriticalSection(&cs);
- ReleaseSemaphore(hWriteSM, 1, NULL);
- Sleep(100 * 1);
- }
- printf("\n******************read1 Terminate \n");
- return 0;
- }
- DWORD WINAPI threadRead2(void *param)
- {
- while(1)
- {
- DWORD dwWait = WaitForSingleObject(hEventRead2Exit, 10);
- if (WAIT_TIMEOUT != dwWait)
- {
- //接收到退出事件后先把资源归还,避免造成死锁
- ReleaseSemaphore(hWriteSM, 1, NULL);
- break;
- }
- WaitForSingleObject(hRead2SM, INFINITE);
- EnterCriticalSection(&cs);
- printf("reader2 process end %d \t", gBook);
- LeaveCriticalSection(&cs);
- ReleaseSemaphore(hWriteSM, 1, NULL);
- Sleep(1000 * 0.5);
- }
- printf("\n******************reader2 Terminate \n");
- return 0;
- }
- DWORD WINAPI threadRead3(void *param)
- {
- while(1)
- {
- //接收到退出事件后先把资源归还,避免造成死锁
- DWORD dwWait = WaitForSingleObject(hEventRead3Exit, 10);
- if (WAIT_TIMEOUT != dwWait)
- {
- ReleaseSemaphore(hWriteSM, 1, NULL);
- break;
- }
- WaitForSingleObject(hRead3SM, INFINITE);
- EnterCriticalSection(&cs);
- printf("reader3 process end %d \t", gBook);
- LeaveCriticalSection(&cs);
- ReleaseSemaphore(hWriteSM, 1, NULL);
- Sleep(1000 * 1);
- }
- printf("\n******************reader3 Terminate \n");
- return 0;
- }
结果如下:

说明:三个读线程读完后,写线程开始写操作,克制结果正确。每次执行时可能结果有所不同,但只有terminate那几行有差异,前面的都相同,原因是当主线程发出通知结束线程事件后,各线程突然跳出,而且无顺序的跳出,线程中等待的时间也有差异,导致这样的结果。
API 练习 第一篇的更多相关文章
- 深入理解javascript选择器API系列第一篇——4种元素选择器
× 目录 [1]id属性 [2]标签名 [3]name属性[4]all 前面的话 说到最常见的DOM应用,恐怕就要数取得特定的某个或某组元素的引用了.DOM定义了许多方式来选取元素,包括getElem ...
- 数据库程序接口——JDBC——API解读第一篇——建立连接的核心对象
结构图 核心对象 Driver Java通过Driver接口表示驱动,每种类型的数据库通过实现Driver接口提供自己的Driver实现类. Driver由属性,操作,事件三部分组成. 属性 公共属性 ...
- ElasticSearch查询 第一篇:搜索API
<ElasticSearch查询>目录导航: ElasticSearch查询 第一篇:搜索API ElasticSearch查询 第二篇:文档更新 ElasticSearch查询 第三篇: ...
- Python爬虫小白入门(四)PhatomJS+Selenium第一篇
一.前言 在上一篇博文中,我们的爬虫面临着一个问题,在爬取Unsplash网站的时候,由于网站是下拉刷新,并没有分页.所以不能够通过页码获取页面的url来分别发送网络请求.我也尝试了其他方式,比如下拉 ...
- 我所理解的RESTful Web API [Web标准篇]
REST不是一个标准,而是一种软件应用架构风格.基于SOAP的Web服务采用RPC架构,如果说RPC是一种面向操作的架构风格,而REST则是一种面向资源的架构风格.REST是目前业界更为推崇的构建新一 ...
- 深入理解this机制系列第一篇——this的4种绑定规则
× 目录 [1]默认绑定 [2]隐式绑定 [3]隐式丢失[4]显式绑定[5]new绑定[6]严格模式 前面的话 如果要问javascript中哪两个知识点容易混淆,作用域查询和this机制绝对名列前茅 ...
- ImageJ 学习第一篇
ImageJ是世界上最快的纯Java的图像处理程序.它可以过滤一个2048x2048的图像在0.1秒内(*).这是每秒40万像素!ImageJ的扩展通过使用内置的文本编辑器和Java编译器的Image ...
- [译]PrestaShop开发者指南 第一篇 基础
# 第一篇 基础 PS(PrestaShop简称)一开始就设定了能够在它的基础上很简单的构建第三方模块的机制,让它成为一款具有极高定制性的电子商务软件. PS的可以在三个方面进行定制: * 主题 * ...
- 微信公众账号开发之微信登陆Oauth授权-第一篇
我曾经在2012年的时候开始研究微信,那时微信的版本还是处于1.0,当时给朋友帮忙做一个基于微信端的web应用,官方的文档是相当少的,百度搜索出来的东西基本也没有多少实用价值,不过是在官网的基础上作了 ...
随机推荐
- Java中的常量池
JVM中有: Class文件常量池.运行时常量池.全局字符串常量池.基本类型包装类对象 常量池 Class文件常量池: class文件是一组以字节为单位的二进制数据流,在java代码的编译期间,编写的 ...
- react 实现类似vue中的<keep-alive>的功能,并解决antd-mobile切换回来时的空白
在移动端的spa页面中,只要使用到了路由就很有必要使用到状态保存的功能,这样才能保证在页面进行切换的时候,让用户可以看到刚才滑动的地方,让用户的体验更加友好.这儿我找到了react-router-ca ...
- python环境变量配置 - CSDN博客
一.下载: 1.官网下载python3.0系列(https://www.python.org/) 2.下载后图标为: 二.安装: Window下: 1.安装路径: 默认安装路径:C:\python35 ...
- Git 比较两个分支之间的差异
1.查看 dev 有,而 master 中没有的: git log dev ^master 2.查看 dev 中比 master 中多提交了哪些内容: git log master..dev 注意,列 ...
- 调试存储过程与declare语句差异
当应用有调用存储过程,而节点有几十个或者上百个,找错是不是一个很麻烦的事情,这个时候,我建议写到数据库中,下面是我做的一个demo. 1. 建立错误日志记录表 drop table PUB_PROC ...
- 记因为电脑名更改而导致sql server一直连接失败
安装的是sql server2016.原先一直用的好好的,直到有一天觉得电脑名称,嗯要改下.改完后,嗯,就忘了. 然后打开sql server,连接失败.一开始以为是sql server配置管理器中的 ...
- windows10 vs2019 + opencv 3.4.7环境搭建
windows vs2019 + opencv 3.4.7环境搭建 安装Opencv 3.4.7 下载 Opencv 第1步 进入 opencv releases 页面,点击 "Window ...
- bzoj1433 假期的宿舍
题意:给你一些人可以睡某某人的床,问是否有所有人都睡下的方案?n<=50. 二分图最大匹配. 用邻接矩阵比较舒服. 标程: #include<cstdio> #include< ...
- 手把手教你接口自动化测试 – SoapUI & Groovy【转】
手把手教你接口自动化测试 – SoapUI & Groovy Posted on 2015-01-21 09:38 WadeXu 阅读(12741) 评论(10) 编辑 收藏 手把手教你接口自 ...
- CF1163E Magical Permutation
题意:给定集合,求一个最大的x,使得存在一个0 ~ 2x - 1的排列,满足每相邻的两个数的异或值都在S中出现过.Si <= 2e5 解:若有a,b,c,令S1 = a ^ b, S2 = b ...