这里主要实现两个线程间通信,当flag = 10 之后通知另外一个线程(也就是“Linux内核多线程(二)”中的程序的各种平台实现)。
首先是C++ 11 的方式:
#include <thread>
#include <iostream>
#include <mutex>
#include <queue>
#include <condition_variable>
#include <atomic>
using namespace std;
const int M = 10;
int main()
{
mutex lockBuffer;
int flag = 0;
bool stop = false;
int count = 0;
condition_variable_any recv_task_cond;
condition_variable_any RecieveTask_cond;
thread recv_task([&]()
{
while(true)
{
std::this_thread::sleep_for (chrono::milliseconds (1000));
lockBuffer.lock ();
if(stop)
{
lockBuffer.unlock();
RecieveTask_cond.notify_one();
break;
}
if (flag == M)
{
cout<< "recv task try to wake up RecieveTask! "<<endl;
count++;
lockBuffer.unlock ();
RecieveTask_cond.notify_one ();
}
else
{
flag++;
lockBuffer.unlock ();
}
}
cout<< "recv_task exit"<<endl;
} );
thread RecieveTask([&]()
{
while(true)
{
std::this_thread::sleep_for (chrono::milliseconds (15));
cout<<"In Recieve Task !" <<endl;
lockBuffer.lock ();
if(flag != M)
{
RecieveTask_cond.wait(lockBuffer);
}
if(stop)
{
lockBuffer.unlock();
recv_task_cond.notify_one();
break;
}
cout<<"WAKE UP "<< count <<" times \t"<<" FLAG = " << flag <<endl;
cout<<endl;
flag = 0;
lockBuffer.unlock ();
recv_task_cond.notify_one ();
}
cout<< "Recieve Task exit "<<endl;
} );
cout<< "Press Enter to stop "<<endl;
getchar();
stop = true;
recv_task.join();
RecieveTask.join();
cout<<"Main Thread"<<endl;
return 0;
}
运行结果:
下面是使用windows提过的API来实现的方式:
#include <stdio.h>
#include <conio.h>
#include <process.h>
#include <windows.h>
HANDLE g_hThreadEvent,g_hevent;
int flag = 0;
CRITICAL_SECTION g_Critical;
unsigned int __stdcall recv_task(void *pPM)
{
printf("%s 启动\n", (PSTR)pPM);
while(1)
{
Sleep(1000);
EnterCriticalSection(&g_Critical);
printf("flag = %d\n", flag++);
if(flag == 10)
SetEvent(g_hThreadEvent);
LeaveCriticalSection(&g_Critical);
}
return 0;
}
unsigned int __stdcall RecieveTask(void *pPM)
{
printf("%s 启动\n", (PSTR)pPM);
while(1)
{
WaitForSingleObject(g_hThreadEvent, INFINITE);
EnterCriticalSection(&g_Critical);
Sleep(5000);
printf("wake up flag = %d\n", flag);
ResetEvent(g_hThreadEvent);
flag = 0;
LeaveCriticalSection(&g_Critical);
}
return 0;
}
int main()
{
InitializeCriticalSection(&g_Critical);
g_hThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
g_hevent = CreateEvent(NULL,FALSE,FALSE,NULL);
HANDLE h[2];
SetEvent(g_hevent);
h[0] = (HANDLE)_beginthreadex(NULL, 0, recv_task, "recv_task", 0, NULL);
h[1] = (HANDLE)_beginthreadex(NULL, 0, RecieveTask, "RecieveTask", 0, NULL);
WaitForMultipleObjects(2,h,TRUE,INFINITE);
CloseHandle(g_hThreadEvent);
return 0;
}
运行结果:
最后是使用posix 线程库实现的方式:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
enum bool{FALSE = 0, TRUE = !FALSE};
int stop;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥锁*/
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;/*初始化条件变量*/
void *RecieveTask(void *);
void *recv_task(void *);
int i = 0;
int main()
{
pthread_t RT;
pthread_t r_t;
stop = TRUE;
pthread_create(&RT,NULL,RecieveTask,(void *)NULL);/*创建进程RecieveTask*/
pthread_create(&r_t,NULL,recv_task,(void *)NULL); /*创建进程recv_task*/
getchar();
stop = FALSE;
//printf("STOP\n");
pthread_join(RT, NULL);/*等待进程recv_task结束*/
printf("BACK IN MAIN \n");
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}
void *recv_task(void *junk)
{
while(stop)
{
pthread_mutex_lock(&mutex);/*锁住互斥量*/
/*
if(stop)
{
pthread_cond_signal(&cond);
printf("END recv_task\n");
break;
}
*/
if(i == 10)
{
pthread_cond_signal(&cond);/*条件改变,发送信号,通知t_b进程*/
pthread_cond_wait(&cond,&mutex);
}
else
printf("recv_task: %d \n",i++);
pthread_mutex_unlock(&mutex);/*解锁互斥量*/
sleep(1);
}
pthread_cond_signal(&cond);
printf("recv_task exit \n");
}
void *RecieveTask(void *junk)
{
while(stop)
{
pthread_mutex_lock(&mutex);
if(i != 10)
pthread_cond_wait(&cond,&mutex);/*等待*/
if(!stop)
{
printf("END RecieveTask \n");
break;
}
printf("wake up RecieveTask: %d \n",i);
i = 0;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
sleep(1);
}
printf("RecieveTask exit \n");
}
运行结果为:
本来还想写一个vxworks下的多线程实现方式(可以通过taskSpawn()函数来创建线程,使用MSG_Q_ID来通信),但是windriver卸载了。。。