多线程练习题
来源:互联网 发布:navicat 编写sql语句 编辑:程序博客网 时间:2024/05/17 00:00
题目描述:
子线程循环 10次,接着主线程循环 100次,接着又回到子线程循环 10次,接着再回到主线程又循环 100次,如此循环50次,试写出代码。
题目解析:首先不计较整体循环50次,只是需要进行一次整体循环,设计两个信号量,一个信号量hThreadSemp,用于计数子线程的输出过程,一个信号量hMainSemp用于计数主线程的输出过程,
首先子线程输出10次,也即在第十次输出完成之后需要,触发信号量hMainSemp,进行主线程信号量增加100,使得主线程进行输出,而后,主线程输出第一百次完成之后触发信号量hThreadSemp,子线程信号量增加10,进行子线程的输出,同上输出10次之后进行主线程信号量的触发,使得主线程输出100次,这样,整体循环就完成了。
#include<iostream>#include<Windows.h>using namespace std;HANDLE hThreadSemp;HANDLE hMainSemp;CRITICAL_SECTION g_cs;int LOOPCOUNT=0;DWORD Thread(LPVOID){DWORD nCount=0;while(1){::WaitForSingleObject(hThreadSemp,INFINITE);::EnterCriticalSection(&g_cs);cout<<"这是子循环第"<<nCount<<"次"<<endl;nCount++;if(nCount==10){LONG ht;::ReleaseSemaphore(hMainSemp,100,&ht);nCount=0;}::LeaveCriticalSection(&g_cs);if(LOOPCOUNT==50){break;}}return 0;}int main(){hThreadSemp=::CreateSemaphoreA(NULL,10,10,NULL);hMainSemp=::CreateSemaphoreA(NULL,0,100,NULL);::InitializeCriticalSection(&g_cs);int nCount=100;LONG thread;HANDLE hThread=NULL;DWORD tmp;if(hThreadSemp!=INVALID_HANDLE_VALUE){hThread=::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Thread,NULL,0,&tmp);}int index=0;while(LOOPCOUNT!=50){//等待子循环执行完10次index++;while(1){::WaitForSingleObject(hMainSemp,INFINITE);::EnterCriticalSection(&g_cs);cout<<"这是主循环第"<<100-nCount<<"次"<<endl;if(100-nCount==99){//继续执行子循环::ReleaseSemaphore(hThreadSemp,10,&thread);::LeaveCriticalSection(&g_cs);break;}nCount--;::LeaveCriticalSection(&g_cs);}//继续执行主循环nCount=100;while(1){::WaitForSingleObject(hMainSemp,INFINITE);::EnterCriticalSection(&g_cs);cout<<"这是主循环第"<<100-nCount<<"次"<<endl;if(100-nCount==99){::ReleaseSemaphore(hThreadSemp,10,&thread);::LeaveCriticalSection(&g_cs);break;}::LeaveCriticalSection(&g_cs);nCount--;}LOOPCOUNT++;nCount=100;}::WaitForSingleObject(hThread,INFINITE);//等待子线程返回::DeleteCriticalSection(&g_cs);CloseHandle(hThreadSemp);CloseHandle(hMainSemp);CloseHandle(hThread);}
这样就能完成我们的需要了。循环50次,每一次主循环中进行四次小的循环
练习题2:编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。
解题思路:我们可以设定三个信号量,信号量A,开始是触发状态,输出A之后,触发信号量B,输出B,随即触发信号量C,输出C,循环十次即可,代码如下:
// 321.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"int _tmain(int argc, _TCHAR* argv[]){return 0;}#include<iostream>#include<Windows.h>using namespace std;int nCount=0;HANDLE hSempA;HANDLE hSempB;HANDLE hSempC;DWORD ThreadA(){while(nCount!=10){::WaitForSingleObject(hSempA,INFINITE);cout<<"A";::ReleaseSemaphore(hSempB,1,NULL);}return 0;}DWORD ThreadB(){while(nCount!=10){::WaitForSingleObject(hSempB,INFINITE);cout<<"B";::ReleaseSemaphore(hSempC,1,NULL);}return 0;}DWORD ThreadC(){while(1){::WaitForSingleObject(hSempC,INFINITE);cout<<"C"<<nCount;cout<<endl;nCount++;if(nCount==10){::ReleaseSemaphore(hSempA,1,NULL);break;}::ReleaseSemaphore(hSempA,1,NULL);}return 0;}int main(){//首先初始化信号量 ABC hSempA=::CreateSemaphoreA(NULL,1,1,NULL);hSempB=::CreateSemaphoreA(NULL,0,1,NULL);hSempC=::CreateSemaphoreA(NULL,0,1,NULL);HANDLE hThreadA,hThreadB,hThreadC;//开辟线程DWORD tmp;hThreadA=::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadA,NULL,0,&tmp);hThreadB=::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadB,NULL,0,&tmp);hThreadC=::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadC,NULL,0,&tmp);::WaitForSingleObject(hThreadA,INFINITE);::WaitForSingleObject(hThreadC,INFINITE);::WaitForSingleObject(hThreadC,INFINITE);CloseHandle(hThreadA);CloseHandle(hThreadB);CloseHandle(hThreadC);CloseHandle(hSempA);CloseHandle(hSempB);CloseHandle(hSempC);}结果如下:
我们可以看到多输出了AB,分析当线程A,第十次输出A,时,nCount的值是9,,然后等待信号量A,被触发,当线程C第十次输出C的时候,触发信号量A,那么线程A就会继续执行,输出多输出了,问题在于等待信号量的过程中nCount可能发生变化,产生了错误,所以信号量触发之后也要检测nCount的值,这样就能完美控制了
// 321.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"int _tmain(int argc, _TCHAR* argv[]){return 0;}#include<iostream>#include<Windows.h>using namespace std;int nCount=0;HANDLE hSempA;HANDLE hSempB;HANDLE hSempC;DWORD ThreadA(){while(nCount!=10){::WaitForSingleObject(hSempA,INFINITE);if(nCount!=10)cout<<"A";::ReleaseSemaphore(hSempB,1,NULL);}return 0;}DWORD ThreadB(){while(nCount!=10){::WaitForSingleObject(hSempB,INFINITE);if(nCount!=10)cout<<"B";::ReleaseSemaphore(hSempC,1,NULL);}return 0;}DWORD ThreadC(){while(1){::WaitForSingleObject(hSempC,INFINITE);cout<<"C"<<nCount;cout<<endl;nCount++;if(nCount==10){::ReleaseSemaphore(hSempA,1,NULL);break;}::ReleaseSemaphore(hSempA,1,NULL);}return 0;}int main(){//首先初始化信号量 ABC hSempA=::CreateSemaphoreA(NULL,1,1,NULL);hSempB=::CreateSemaphoreA(NULL,0,1,NULL);hSempC=::CreateSemaphoreA(NULL,0,1,NULL);HANDLE hThreadA,hThreadB,hThreadC;//开辟线程DWORD tmp;hThreadA=::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadA,NULL,0,&tmp);hThreadB=::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadB,NULL,0,&tmp);hThreadC=::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadC,NULL,0,&tmp);::WaitForSingleObject(hThreadA,INFINITE);::WaitForSingleObject(hThreadC,INFINITE);::WaitForSingleObject(hThreadC,INFINITE);CloseHandle(hThreadA);CloseHandle(hThreadB);CloseHandle(hThreadC);CloseHandle(hSempA);CloseHandle(hSempB);CloseHandle(hSempC);}
练习题三:
有四个线程1、2、3、4。线程1的功能就是输出1,线程2的功能就是输出2,以此类推.........现在有四个文件ABCD。初始都为空。现要让四个文件呈如下格式:
A:1 2 3 4 1 2....
B:2 3 4 1 2 3....
C:3 4 1 2 3 4....
D:4 1 2 3 4 1....
解题思路:设置4个信号量,第一次进行输出的饿时候
SemA ----A1
SemB ----A2 B2
SemC ----A3 B3 C3
SemD ----A4 B4 C4 D4
第2...3..4次输出的时候就是
SemA ----A1 B1 C1 D1
SemB ----A2 B2 C2 D2
SemC ----A3 B3 C3 D3
SemD ----A4 B4 C4 D4
区别第一次输出的时候,就可以完美实现结果了,等待实现源代码// 321.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"int _tmain(int argc, _TCHAR* argv[]){return 0;}#include<iostream>#include<Windows.h>#include<fstream>using namespace std;HANDLE hSempA,hSempB,hSempC,hSempD;bool isFirst=true;HANDLE hThread[4]={0};void WriteFile(char m){ofstream out("A.txt",ios::app);out.write(&m,1);out.close();cout<<"A.txt "<<m<<"\n";out.open("B.txt",ios::app);out.write(&m,1);out.close();cout<<"B.txt "<<m<<"\n";out.open("C.txt",ios::app);out.write(&m,1);out.close();cout<<"C.txt "<<m<<"\n";out.open("D.txt",ios::app);out.write(&m,1);out.close();cout<<"D.txt "<<m<<"\n";}DWORD ThreadA(){while(true){if(isFirst){::WaitForSingleObject(hSempA,INFINITE);if(isFirst){ofstream out("A.txt",ios::app);out.write("1",strlen("1"));out.close();cout<<"A.txt "<<"1\n";::ReleaseSemaphore(hSempB,1,NULL);}else{WriteFile('1');::ReleaseSemaphore(hSempB,1,NULL);}}else{::WaitForSingleObject(hSempA,INFINITE);WriteFile('1');::ReleaseSemaphore(hSempB,1,NULL);}}return 0;}DWORD ThreadB(){while(1){if(isFirst){::WaitForSingleObject(hSempB,INFINITE);if(isFirst){ofstream out("A.txt",ios::app);out.write("2",strlen("2"));out.close();cout<<"A.txt "<<"2\n";out.open("B.txt",ios::app);out.write("2",strlen("2"));out.close();cout<<"B.txt "<<"2\n";::ReleaseSemaphore(hSempC,1,NULL);}else{WriteFile('2');::ReleaseSemaphore(hSempC,1,NULL);}}else{::WaitForSingleObject(hSempB,INFINITE);WriteFile('2');::ReleaseSemaphore(hSempC,1,NULL);}}return 0;}DWORD ThreadC(){while(1){if(isFirst){::WaitForSingleObject(hSempC,INFINITE);if(isFirst){ofstream out("A.txt",ios::app);out.write("3",strlen("3"));out.close();cout<<"A.txt "<<"3\n";out.open("B.txt",ios::app);out.write("3",strlen("3"));out.close();cout<<"B.txt "<<"3\n";out.open("C.txt",ios::app);out.write("3",strlen("3"));out.close();cout<<"C.txt "<<"3\n";::ReleaseSemaphore(hSempD,1,NULL);}else{WriteFile('3');::ReleaseSemaphore(hSempD,1,NULL);}}else{::WaitForSingleObject(hSempC,INFINITE);WriteFile('3');::ReleaseSemaphore(hSempD,1,NULL);}}return 0;}DWORD ThreadD(){while(1){if(isFirst){::WaitForSingleObject(hSempD,INFINITE);ofstream out("A.txt",ios::app);out.write("4",strlen("4"));out.close();cout<<"A.txt "<<"4\n";out.open("B.txt",ios::app);out.write("4",strlen("4"));out.close();cout<<"B.txt "<<"4\n";out.open("C.txt",ios::app);out.write("4",strlen("4"));out.close();cout<<"C.txt "<<"4\n";out.open("D.txt",ios::app);out.write("4",strlen("4"));out.close();cout<<"D.txt "<<"4\n";isFirst=false;::ReleaseSemaphore(hSempA,1,NULL);}else{::WaitForSingleObject(hSempD,INFINITE);WriteFile('4');::ReleaseSemaphore(hSempA,1,NULL);}}return 0;}int main(){::DeleteFileA("A.txt");::DeleteFileA("B.txt");::DeleteFileA("C.txt");::DeleteFileA("D.txt");hSempA=::CreateSemaphoreA(NULL,1,1,NULL);hSempB=::CreateSemaphoreA(NULL,0,1,NULL);hSempC=::CreateSemaphoreA(NULL,0,1,NULL); hSempD=::CreateSemaphoreA(NULL,0,1,NULL);DWORD tmp=0;hThread[0]=::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadA,NULL,0,&tmp);hThread[1]=::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadB,NULL,0,&tmp);hThread[2]=::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadC,NULL,0,&tmp);hThread[3]=::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadD,NULL,0,&tmp);::WaitForMultipleObjects(4,hThread,true,INFINITE);return 0;}
这里有一个之前重复出现的问题就是在进行标志位判断的时候(本题中是isFirst)首先进行判断,而后是等待信号量触发,(这里面就容易出问题了),在等待信号量触发的过程中就出现了,如果有其他的线程已经将isFirst触发了,而我们已经检测过了,isFirst是未触发状态,所以我们就需要进行再次判断,如果没有已经触发,则进行触发操作,否则进行未触发操作
- 多线程练习题
- 多线程练习题
- 多线程练习题
- C多线程练习题
- 多线程练习题(一)
- 多线程练习题(一)
- 多线程练习题(二)
- 多线程练习题(三)
- java--多线程练习题
- Java多线程---生产者消费者练习题
- java学习之路 之 多线程练习题
- 多线程同步问题-练习题1-笔记整理
- 多线程同步问题-练习题2-笔记整理
- 多线程同步问题-练习题3-笔记整理
- Java基础练习题 (8)多线程
- 短实习---Java多线程(练习题)
- <MFC多线程> 某培训机构的多线程练习题
- java多线程(六) 之 店铺买卖多线程练习题
- A*搜索算法
- 面试大总结之二:Java搞定面试中的二叉树题目
- 什么是滚动优化(receding-horizon/rolling-horizon)?
- 基于 maven 构件的 spring mvc 框架搭建
- linux shell下的输入输出重定向
- 多线程练习题
- android onTouch()与onTouchEvent()的区别
- 关于citynight.cn&mekor.cn空间忘了续费导致所有资料丢失
- 看到别人用css3写的baymax ,大白,挺萌的
- python 简单图像处理(8) 直方图均衡化
- 关于Android的SDK更新下载过程说明
- 我的企业消费黑名单
- java解析properties文件
- OpenCV 旋转向量与旋转矩阵转化(罗德里格斯 )