子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码。
从图中们可以看到,主线程的执行每次都依赖于子线程,只有子线程执行完才执行主线程.
一个线程依赖于另一个线程的实现,那就是同步.
使用event或者semaphore实现:
一个线程依赖于另一个线程的实现,那就是同步.
使用event或者semaphore实现:
我用event实现,比较简单.
#include <iostream>
#include <windows.h>
#include <process.h>
int g_count = 10;
HANDLE g_ThreadEventSon ,g_ThreadEventFather, g_threadMutex,g_threadSemaphore ;
unsigned int __stdcall ThreadFun(void *pthread_num)
{
for ( int i=0 ; i<g_count ;++ i ){
WaitForSingleObject(g_ThreadEventFather ,INFINITE);
std::cout <<"子线程开始循环\n";
for ( int j =0; j<10; ++ j ){
std::cout <<j<< " ";
}
std::cout <<std::endl;
SetEvent(g_ThreadEventSon );
}
return 0;
}
int main ()
{
g_ThreadEventSon = CreateEvent(NULL ,false,false,NULL);
g_ThreadEventFather = CreateEvent(NULL ,false,true,NULL);
HANDLE h =(HANDLE ) _beginthreadex( NULL,0,ThreadFun ,NULL,0, NULL);
for ( int i=0 ; i<g_count ;++ i ){
WaitForSingleObject(g_ThreadEventSon ,INFINITE);
std::cout <<"主线程开始循环\n";
for ( int j =0; j<100; ++ j ){
std::cout <<j<< " ";
}
std::cout <<std::endl;
SetEvent(g_ThreadEventFather );
}
CloseHandle( g_ThreadEventFather);
CloseHandle( g_ThreadEventSon);
return 0;
}
编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。
创建3个线程依次打印ABC用同步方法道理一样,不再赘述.
方法1:用event实现:(同步)
#include <iostream>
#include <windows.h>
#include <process.h>
int g_count = 10;
HANDLE g_Event_A ,g_Event_B, g_Event_C;
unsigned int __stdcall ThreadFunA(void *pthread_num)
{
for ( int i=0 ; i<g_count ;++ i ){
WaitForSingleObject(g_Event_A ,INFINITE);
std::cout <<"A";
SetEvent(g_Event_B );
}
return 0;
}
unsigned int __stdcall ThreadFunC(void *pthread_num)
{
for ( int i=0 ; i<g_count ;++ i ){
WaitForSingleObject(g_Event_C ,INFINITE);
std::cout <<"C";
SetEvent(g_Event_A );
}
return 0;
}
unsigned int __stdcall ThreadFunB(void *pthread_num)
{
for ( int i=0 ; i<g_count ;++ i ){
WaitForSingleObject(g_Event_B ,INFINITE);
std::cout <<"B";
SetEvent(g_Event_C );
}
return 0;
}
int main ()
{
g_Event_A = CreateEvent(NULL ,false,true,NULL);
g_Event_B = CreateEvent(NULL ,false,false,NULL);
g_Event_C = CreateEvent(NULL ,false,false,NULL);
HANDLE h[3];
h[0] =( HANDLE) _beginthreadex (NULL,0, ThreadFunA,NULL ,0,NULL);
h[1] =( HANDLE) _beginthreadex (NULL,0, ThreadFunB,NULL ,0,NULL);
h[2] =( HANDLE) _beginthreadex (NULL,0, ThreadFunC,NULL ,0,NULL);
WaitForMultipleObjects(3, h,true ,INFINITE);
CloseHandle( g_Event_A);
CloseHandle( g_Event_B);
CloseHandle( g_Event_C);
return 0;
}
方法2:用临界区实现(互斥)
使用临界区的核心思想在于,每个线程进入临界区后判断是不是该他输出了,轮到他输出就输出,否则退出临界区.
#include <iostream>
#include <windows.h>
#include <process.h>
int g_count = 10;
int g_num = 0;
int g_curr = 0;
CRITICAL_SECTION g_critical_section;
unsigned int __stdcall ThreadFun (void * pthread_num)
{
char ID;
int num;
int loop = 0;
EnterCriticalSection(& g_critical_section );
ID = g_num+ 'A';
num = g_num++;
LeaveCriticalSection(& g_critical_section );
while ( loop <10 ){
EnterCriticalSection (&g_critical_section );
if ( num == g_curr ){
std ::cout << ID;
loop ++;
g_curr = ++g_curr %3;
}
LeaveCriticalSection (&g_critical_section );
}
return 0;
}
int main ()
{
InitializeCriticalSection(& g_critical_section );
HANDLE h [3];
for ( int i=0 ; i<3; ++ i ){
h [i ] =( HANDLE) _beginthreadex (NULL ,0, ThreadFun, NULL ,0,NULL );
}
WaitForMultipleObjects(3, h ,true , INFINITE);
return 0;
}有四个线程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....
请设计程序。
请设计程序。核心思想和上一个用临界区实现方法一样.临界区方法实现:#include <iostream>
#include <windows.h>
#include <process.h>
int g_count = 10;
int g_num = 0;
int fileNum [4];
CRITICAL_SECTION g_critical_section;
unsigned int __stdcall ThreadFun (void * pthread_num)
{
int num;
int loop = 0;
int fileCount[4];
for ( int i=0; i<4; ++ i ){
fileCount [i ] = 0;
}
EnterCriticalSection(& g_critical_section );
num = g_num++;
LeaveCriticalSection(& g_critical_section );
while ( loop <12 ){
EnterCriticalSection (&g_critical_section );
for ( int i=0; i<4; ++ i ){
if ( fileNum [ i] == num && fileCount [i ]<3){
fileNum [i ] = ( fileNum[ i ]+1)%4;
fileCount [i ]++;
std ::cout <<( char)( 'A' + i )<< ":" << num +1<< std :: endl;
loop ++;
}
}
LeaveCriticalSection (&g_critical_section );
}
return 0;
}
int main ()
{
for ( int i=0; i<4 ; ++ i ){
fileNum [i ] = i;
}
InitializeCriticalSection(& g_critical_section );
HANDLE h [4];
for ( int i=0 ; i<4; ++ i ){
h [i ] =( HANDLE) _beginthreadex (NULL ,0, ThreadFun, NULL ,0,NULL );
}
WaitForMultipleObjects(4, h ,true , INFINITE);
return 0;
}
分析结果:
我们看一下开头和结尾就好了,中间数据不必关心.
文件我用ABCD替代,线程我用1,2,3,4替代,例如A:1表示线程1向文件A写入1.
现在我们来分析一下结果:
对于A:从1开始,以4结尾,中间总是1,2,3,4的循环符合要求.
对于B:以2开始,以1结尾,中间总是23412341的循环
对于c和d类似,不在分析
结果满足要求.
1060

被折叠的 条评论
为什么被折叠?



