1、Windows
#include <stdio.h>
#include <process.h>
#include <windows.h>
// 线程个数
const int THREAD_NUM = 3;
// 循环次数
const int LOOP = 10;
// 子线程同步事件
HANDLE g_hThreadEvent[THREAD_NUM];
// 主线程与子线程同步
HANDLE g_Semaphore;
int g_Count = 0;
unsigned int __stdcall ThreadFunction(void *pPM)
{
int num = *(int *)pPM;
// 信号量++
ReleaseSemaphore(g_Semaphore, 1, NULL);
for (int i = 0; i < LOOP; i++)
{
// 等待该事件有效。
WaitForSingleObject(g_hThreadEvent[num], INFINITE);
g_Count++;
printf("第%d次 线程ID:%3d,线程打印:%c\n ", g_Count, GetCurrentThreadId(), num + 'A');
// 置位下一个事件有效。
SetEvent(g_hThreadEvent[(num + 1) % THREAD_NUM]);
}
return 0;
}
int main(void)
{
int i = 0;
HANDLE hThreadHandle[THREAD_NUM];
// 形参1:安全控制,一般为NULL
// 形参2:资源的初始值。
// 形参3:最大的资源数量。
// 形参4:该信号量的名称。
g_Semaphore = CreateSemaphore(NULL, 0, 1, NULL); // 当前0个资源,最大允许1个同时访问
for (i = 0; i < THREAD_NUM; i++)
{
// 形参1:安全控制。
// 形参2:该事件是手动复原(TRUE)还是自动复原(FALSE)。
// 形参3:指定事件的初始状态。若为TRUE,则为有信号状态,若为FALSE,则为无信号状态。
// 形参4:指定该事件的名称。
g_hThreadEvent[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
}
for (i = 0; i < THREAD_NUM; i++)
{
// 创建线程
hThreadHandle[i] = (HANDLE)_beginthreadex(nullptr, 0, ThreadFunction, &i, 0, nullptr);
// 每次创建完线程,该信号量都会等待,直至线程执行到释放信号量的代码为止。
WaitForSingleObject(g_Semaphore, INFINITE);
}
// 代码执行到这里,说明各个线程都已经执行到WaitForSingleObject,在等待确认信号。
// 置位线程1的事件。
SetEvent(g_hThreadEvent[0]);
// 等待所有线程返回。
WaitForMultipleObjects(THREAD_NUM, hThreadHandle, true, INFINITE);
for (i = 0; i < THREAD_NUM; i++)
{
CloseHandle(hThreadHandle[i]);
CloseHandle(g_hThreadEvent[i]);
}
CloseHandle(g_Semaphore);
system("pause");
return 0;
}
2、Linux
#include <iostream>
#include <pthread.h>
#include <unistd.h>
// 标记指定的线程是否处于等待 cond 的状态。
// 1 处于等待 cond 的状态。
// 0 cond 已成立或者处于阻塞状态。
bool g_flag_CA, g_flag_AB, g_flag_BC;
pthread_mutex_t g_mtx = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t g_condCA = PTHREAD_COND_INITIALIZER;
pthread_cond_t g_condAB = PTHREAD_COND_INITIALIZER;
pthread_cond_t g_condBC = PTHREAD_COND_INITIALIZER;
using PRINTFUNC = void *(*)(void *);
char g_cinfo[3] = {'A', 'B', 'C'};
char g_showcount = 10;
void MyCondWait(bool *pflag, pthread_cond_t *pcond, pthread_mutex_t *pmtx);
void MyCondSignal(bool *pflag, pthread_cond_t *pcond, pthread_mutex_t *pmtx);
void *PrintA(void *arg);
void *PrintB(void *arg);
void *PrintC(void *arg);
int main()
{
PRINTFUNC printfunc[3] = {
PrintA,
PrintB,
PrintC};
const size_t threadcount = sizeof(printfunc) / sizeof(PRINTFUNC);
pthread_t thread_pid[threadcount] = {0};
for (size_t i = 0; i < threadcount; i++)
{
if (pthread_create(thread_pid + i, nullptr, printfunc[i], (void *)(g_cinfo + i)) != 0)
{
std::cout << "Failed to create thread." << std::endl;
exit(1);
}
}
// 加 sleep(1) 的作用是使三个线程在执行完 sleep(1) 之后,
// 均堵塞在 pthread_cond_wait 。等待各自的条件的释放。
sleep(1);
pthread_mutex_lock(&g_mtx);
MyCondSignal(&g_flag_CA, &g_condCA, &g_mtx);
pthread_mutex_unlock(&g_mtx);
for (size_t i = 0; i < threadcount; i++)
{
pthread_join(thread_pid[i], nullptr);
}
return 0;
}
void *PrintA(void *arg)
{
char cinfo = *(char *)arg;
char showcount = g_showcount;
while (showcount--)
{
pthread_mutex_lock(&g_mtx);
MyCondWait(&g_flag_CA, &g_condCA, &g_mtx);
std::cout << 10 - showcount << "." << cinfo;
MyCondSignal(&g_flag_AB, &g_condAB, &g_mtx);
pthread_mutex_unlock(&g_mtx); // 解的锁是 pthread_cond_wait 满足条件时加的锁。
usleep(50);
}
// 防止线程 C ,在执行 MyCondSignal 函数时,由于 g_flag_CA = 0,导致程序执行在 while 循环中。
g_flag_CA = true;
return nullptr;
}
void *PrintB(void *arg)
{
char cinfo = *(char *)arg;
char showcount = g_showcount;
while (showcount--)
{
pthread_mutex_lock(&g_mtx);
MyCondWait(&g_flag_AB, &g_condAB, &g_mtx);
std::cout << cinfo;
MyCondSignal(&g_flag_BC, &g_condBC, &g_mtx);
pthread_mutex_unlock(&g_mtx);
usleep(50);
}
return nullptr;
}
void *PrintC(void *arg)
{
char cinfo = *(char *)arg;
char showcount = g_showcount;
while (showcount--)
{
pthread_mutex_lock(&g_mtx);
MyCondWait(&g_flag_BC, &g_condBC, &g_mtx);
std::cout << cinfo << std::endl;
MyCondSignal(&g_flag_CA, &g_condCA, &g_mtx);
pthread_mutex_unlock(&g_mtx);
usleep(50);
}
return nullptr;
}
// 标记并使指定的线程处于等待 cond 满足的状态。
void MyCondWait(bool *pflag, pthread_cond_t *pcond, pthread_mutex_t *pmtx)
{
*pflag = true;
pthread_cond_wait(pcond, pmtx);
*pflag = false;
return;
}
// 向指定的线程发出条件允许的通知。
void MyCondSignal(bool *pflag, pthread_cond_t *pcond, pthread_mutex_t *pmtx)
{
while (!*pflag)
{
// 执行到这里,说明该线程阻塞在 while 循环开头的 pthread_mutex_lock 函数位置。
// 需要调用 pthread_mutex_unlock() 函数将其解锁并执行到 pthread_cond_wait() 函数,使之处于等
// 待 cond 的状态。
pthread_mutex_unlock(&g_mtx);
usleep(50);
pthread_mutex_lock(&g_mtx);
}
// 执行到这里,说明指定的线程已经处于等待 cond 满足的状态。
pthread_cond_signal(pcond);
return;
}
(SAW:Game Over!)