写在开头
前端时间在工作中遇到一个使用场景,要设计三个线程分别执行执行三个任务,并且需要按照1,2,3的顺序循环执行。研究了一下C++中常用的互斥机制,最后使用C++11中的条件变量实现了上述业务场景的需求。关于C++11中的条件变量,本文不做详细介绍,直接上代码实现,代码可直接编译运行。
/*
基于C++11的条件变量实现多线程同步的功能
*/
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
//线程运行的条件
enum ThreadRunConditionType : unsigned short
{
ThreadRunCondition1,//线程1运行的条件
ThreadRunCondition2,//线程2运行的条件
ThreadRunCondition3,//线程3运行的条件
};
//条件类型
ThreadRunConditionType ThreadRunCondition;
//控制三个线程按1,2,3顺序依次执行的条件变量
std::condition_variable condiVar;
std::mutex mutex;
//最后一个线程执行完后,通知第一个线程重新开始执行的条件变量
std::condition_variable condiVar2;
std::mutex mutex2;
//控制循环执行次数
#define LOOP_RUNNING_NUMBERS 0xffffffff
bool isRunning(int index)
{
return (index <= LOOP_RUNNING_NUMBERS);
}
void MyThreadProc1(std::string guid)
{
unsigned int index = 0;
while (1)
{
{
//do somethings in thread1
std::unique_lock<std::mutex> lock(mutex);
std::cout << guid.c_str() << " : " << index++ << std::endl;
//线程1任务执行完成后,更新线程执行条件为线程2的条件,并通知其他线程
ThreadRunCondition = ThreadRunCondition2;
condiVar.notify_all();
}
//condiVar.notify_all();
{
//等待线程3执行结束后的通知
std::unique_lock<std::mutex> lock(mutex2);
//condiVar2.wait_for(lock, std::chrono::milliseconds(1000));
condiVar2.wait(lock);
}
if (!isRunning(index))
{
break;
}
}
}
void MyThreadProc2(std::string guid)
{
unsigned int index = 0;
while (1)
{
{
//等待条件变量满足线程2执行的条件
std::unique_lock<std::mutex> lock(mutex);
condiVar.wait(lock, [] {return (ThreadRunCondition2 == ThreadRunCondition); });
//condiVar.wait_for(lock, std::chrono::milliseconds(100), [] {return (ThreadRunCondition2 == ThreadRunCondition); });
//do somethings in thread2
std::cout << guid.c_str() << " : " << index++ << std::endl;
ThreadRunCondition = ThreadRunCondition3;
condiVar.notify_all();
}
//将线程执行条件更新为满足线程3的条件,并发出条件变量释放的通知
//condiVar.notify_all();
if (!isRunning(index))
{
break;
}
}
}
void MyThreadProc3(std::string guid)
{
unsigned int index = 0;
while (1)
{
{
//等待条件变量满足线程3执行的条件
std::unique_lock<std::mutex> lock(mutex);
condiVar.wait(lock, [] {return (ThreadRunCondition3 == ThreadRunCondition); });
//do somethings in thread2
std::cout << guid.c_str() << " : " << index++ << std::endl << std::endl;
//将线程执行条件更新为满足线程1的条件
ThreadRunCondition = ThreadRunCondition1;
}
{
//通知线程1,可以重新开始执行新一轮的任务
std::unique_lock<std::mutex> lock(mutex2);
condiVar2.notify_all();
}
if (!isRunning(index))
{
break;
}
}
}
int main()
{
std::string guid1 = "testthrea#####1";
std::string guid2 = "testthrea$$$$$2";
std::string guid3 = "testthrea&&&&&3";
std::thread th1(MyThreadProc1, guid1);
std::thread th2(MyThreadProc2, guid2);
std::thread th3(MyThreadProc3, guid3);
th1.join();
th2.join();
th3.join();
system("pause");
return 0;
}
运行结果如下图:
测试循环运行1000次顺序都是正常的,博主也作过无限次数运行,运行结果顺序一直正常。