c++多线程实现循环打印ABC
来源:互联网 发布:spss分析数据的步骤 编辑:程序博客网 时间:2024/05/17 07:36
网上的资料基本都是java实现的,c++的很少,加上win32的API函数对我个人而言晦涩难懂,真是举步维艰~
目前而言对我来说最好理解的,最简单的,是使用Event。
首先明白Event的用法:秒杀多线程第六篇 经典线程同步 事件Event
CreateEvent
函数功能:创建事件
//函数原型:HANDLECreateEvent( LPSECURITY_ATTRIBUTESlpEventAttributes, BOOLbManualReset, BOOLbInitialState, LPCTSTRlpName);
函数说明:
- 第一个参数表示安全控制,一般直接传入NULL。
- 第二个参数确定事件是手动置位还是自动置位,传入TRUE表示手动置位,传入FALSE表示自动置位。如果为自动置位,则对该事件调用WaitForSingleObject()后会自动调用ResetEvent()使事件变成未触发状态。打个小小比方,手动置位事件相当于教室门,教室门一旦打开(被触发),所以有人都可以进入直到老师去关上教室门(事件变成未触发)。自动置位事件就相当于医院里拍X光的房间门,门打开后只能进入一个人,这个人进去后会将门关上,其它人不能进入除非门重新被打开(事件重新被触发)。
(此中有坑)- 第三个参数表示事件的初始状态,传入TRUR表示已触发。
- 第四个参数表示事件的名称,传入NULL表示匿名事件。
SetEvent
函数功能:触发事件
函数原型:BOOLSetEvent(HANDLEhEvent);
函数说明:每次触发后,必有一个或多个处于等待状态下的线程变成可调度状态。
ResetEvent
函数功能:将事件设为末触发
函数原型:BOOLResetEvent(HANDLEhEvent);
最简单的实现是,先分别创建三个线程分别打印对应次数的字母A/B/C,还有三个事件event ,其中每个线程在打印的时候使用waitforsingleobject来阻塞,只有wait到了对应的事件,才可以输出对应的字母,然后打印完毕后,用setevent把下一个事件触发,然后执行下一个事件。
最简单的代码:
using namespace std;const int NUM = 3;int nCount = 1; //用来表示先打印哪一个 0-A,1-B,2-CHANDLE g_Event[NUM] = { NULL };//三个事件unsigned int WINAPI funA(LPVOID pM){ for (int i = 0; i < 100; i++) { WaitForSingleObject(g_Event[0], INFINITE); //等待g_Event[0],然后才执行打印A; cout << 'A'; Sleep(100); nCount ++ ; SetEvent(g_Event[(nCount) % NUM]); } return 0;}unsigned int WINAPI funB(LPVOID pM){ for (int i = 0; i < 100; i++) { WaitForSingleObject(g_Event[1], INFINITE); cout << 'B'; Sleep(100); nCount++; SetEvent(g_Event[(nCount) % NUM]); } return 0;}unsigned int WINAPI funC(LPVOID pM){ for (int i = 0; i < 100; i++) { WaitForSingleObject(g_Event[2], INFINITE); cout << 'C'; Sleep(100); nCount++; SetEvent(g_Event[(nCount) % NUM]); } return 0;}int main(){ HANDLE threads[NUM] = { NULL }; for (unsigned int i = 0; i < 3; i++) { g_Event[i] = CreateEvent(NULL, FALSE, FALSE, NULL); //这里的第二个参数是False,意思是这个事件执行完后,会自动设置为未触发状态(形参3的参数就是设置默认是否为触发),如果是TRUE,则需要执行完后手动置为未触发,用ResetEvent函数即可。 } threads[0] = (HANDLE)_beginthreadex(NULL, 0, funA, NULL, 0, NULL); threads[1] = (HANDLE)_beginthreadex(NULL, 0, funB, NULL, 0, NULL); threads[2] = (HANDLE)_beginthreadex(NULL, 0, funC, NULL, 0, NULL); SetEvent(g_Event[nCount]); WaitForMultipleObjects(NUM, threads, TRUE, INFINITE); CloseHandle(g_Event[0]); CloseHandle(g_Event[1]); CloseHandle(g_Event[2]); memset(g_Event, 0, sizeof(HANDLE)*NUM); CloseHandle(threads[0]); CloseHandle(threads[1]); CloseHandle(threads[2]); memset(threads, 0, sizeof(HANDLE)*NUM); return 0;}
写的太复杂了,还用了EVENT数组,简直是没有困难创造困难。
下面的这个代码就很好理解。
http://blog.csdn.net/bupt8846/article/details/45541723
#include <stdio.h> #include <windows.h> #include<iostream> #include <process.h> #include <time.h> using namespace std; HANDLE g_a, g_b, g_c; CRITICAL_SECTION g_cs; unsigned int __stdcall PrintA(void* pM) { int i = 0; while (i < 10) { WaitForSingleObject(g_a, INFINITE); //EnterCriticalSection(&g_cs); cout <<i+1<< ": A"; ++i; SetEvent(g_b); //LeaveCriticalSection(&g_cs); } return 0; } unsigned int __stdcall PrintB(void* pM) { int i = 0; while (i < 10) { WaitForSingleObject(g_b, INFINITE); //EnterCriticalSection(&g_cs); cout << 'B'; ++i; SetEvent(g_c); //LeaveCriticalSection(&g_cs); } return 0; } unsigned int __stdcall PrintC(void* pM) { int i = 0; while (i < 10) { WaitForSingleObject(g_c, INFINITE); //EnterCriticalSection(&g_cs); cout << "C\n"; ++i; SetEvent(g_a); //LeaveCriticalSection(&g_cs); } return 0; } int _tmain(int argc, _TCHAR* argv[]) { InitializeCriticalSection(&g_cs); g_a = CreateEvent(NULL, FALSE, TRUE, NULL); //这里设置为TRUE,默认g_a是触发的。 g_b = CreateEvent(NULL, FALSE, FALSE, NULL); g_c = CreateEvent(NULL, FALSE, FALSE, NULL); HANDLE threads[3]; threads[0] = (HANDLE)_beginthreadex(NULL, 0, PrintA, NULL, 0, NULL); threads[1] = (HANDLE)_beginthreadex(NULL, 0, PrintB, NULL, 0, NULL); threads[2] = (HANDLE)_beginthreadex(NULL, 0, PrintC, NULL, 0, NULL); WaitForMultipleObjects(3, threads, TRUE, INFINITE); CloseHandle(g_a); CloseHandle(g_b); CloseHandle(g_c); CloseHandle(threads[0]); CloseHandle(threads[1]); CloseHandle(threads[2]); DeleteCriticalSection(&g_cs); cout << endl; system("pause"); return 0; }
简单的版本,避免代码重复太多。
using namespace std;const int NUM = 3;int nCount = 1;HANDLE g_Event[NUM] = { NULL };//HANDLE g_Mutex = NULL ;unsigned int WINAPI fun(LPVOID pM){ int nParam = (int)pM; char res = 'A' + nParam; for (int i = 0; i < 100; i++) { WaitForSingleObject(g_Event[nParam], INFINITE); cout << res; Sleep(100); ResetEvent(g_Event[nParam]); SetEvent(g_Event[(nParam + 1) % NUM]); //触发下一个事件 } return 0;}int main(){ HANDLE threads[NUM] = { NULL }; for (unsigned int i = 0; i < 3; i++) { g_Event[i] = CreateEvent(NULL, FALSE, FALSE, NULL); threads[i] = (HANDLE)_beginthreadex(NULL, 0, fun, (void *)i, 0, NULL); } SetEvent(g_Event[nCount]); WaitForMultipleObjects(NUM, threads, TRUE, INFINITE); CloseHandle(g_Event[0]); CloseHandle(g_Event[1]); CloseHandle(g_Event[2]); memset(g_Event, 0, sizeof(HANDLE)*NUM); CloseHandle(threads[0]); CloseHandle(threads[1]); CloseHandle(threads[2]); memset(threads, 0, sizeof(HANDLE)*NUM); return 0;}
阅读全文
0 0
- c++多线程实现循环打印ABC
- 多线程循环打印ABC
- Java多线程--三个线程分别打印a,b,c.请用多线程实现循环打印15次abc
- 多线程之——实现循环打印"abc"
- 多线程之三个ABC线程实现循环打印100次
- Java多线程 循环打印ABC 10次
- 多线程(至少三个线程)分别打印A、B、C,要求按ABC的顺序循环打印10次。
- 【机试】华为2014校招机试:多线程循环打印十次ABC
- 多线程顺序打印ABC
- JAVA多线程打印ABC
- 多线程打印abc
- 题目:有三个线程分别打印A、B、C,请用多线程编程实现,在屏幕打印10次ABC
- 多线程顺序打印ABC的三种实现---join方法
- 多线程交替打印ABC的多种实现方法
- 多线程交替打印ABC的多种实现方法
- 三个线程循环打印ABC。。。。
- Java循环打印ABC…
- java多线程顺序打印ABC
- 第一章 广义动能定理和系统思考
- Common Subsequence(相同字符的总数dp)
- 1.1.2 兰切斯特第二法则
- 浅谈神经网络反向传播的梯度丢失问题
- 1.1.2.2 兰切斯特第二法则的阐释
- c++多线程实现循环打印ABC
- Ubuntu 16.04 nvidia cuda cudnn tensorflow-gpu 配置
- 南通博得——南通java培训学员就业情况就是好
- web 服务器阿里云基本使用(Ubuntu16.04LTS)
- 1.1.2.3兰切斯特第二法则的动能定…
- 1.1.2.3.6 近距离作战与战术包围
- Visual Studio 更改字体大小显示行号和更改主题(背景)颜色
- 1.1.2.3.11 兵力的投入数量与胜利
- 一个有效的bat程序中输入密码不回显并显示星号*