1.需求
1.处理一个列表的数据,要求按照列表的数据处理10个数据
2.可以使用多线程处理,但是针对每个线程,1~10的处理顺序不能变。
3.每个数据的处理必须原子,即只有一个线程可以针对某个数据进行处理,但是10个数据是可以由10个线程并行处理的。只是有前面的单线程内的处理顺序要求。
2.设计
设计一个处理的监控链,为每个数据定义一个线程监控的指针,叫监控指针。
为每个线程定义一个激活指针,如果有线程需要激活那么就通过该指针激活等待中的线程。
比如线程1开始处理数据1了,那么就把自己的指针设置给数据1的监控指针。
这时候如果线程2也想处数据1,会有两种情况,如下分别处理
情况1:数据没有任何线程锁定,那么按照线程1的方式处理数据1
情况2:线程1正在处理数据,那么我把我的指针设置给线程1的激活指针,同时把我的指针设置给数据1的监控指针。这时候如果有线程3要处理数据1,处理的方和线程2的处理方法相同。
这个设计的关键就是两个指针,如下用类图说明。
类图如下:
3.代码
#include <iostream>
#include <thread>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <windows.h>
using namespace std;
class BoxDatas;
class MyThred;
std::mutex printmtx;
//数据处理对象
class Data
{
public:
int id = 0;
int count = 0;
};
class BoxData
{
public:
Data data;
BoxData(int id){
data.id = id;
}
MyThred* handelThread = NULL;
std::mutex mtx;
};
//数据容器承担多线程的处理对数据的保护功能
class BoxDatas
{
public:
static BoxDatas my;
static BoxDatas getMy() {
return my;
}
static const int max = 10;
BoxDatas() {
for (int i = 0; i < max; i++)
{
bs[i] = new BoxData(i);
}
}
BoxData* bs[max];
//所有数据加工只都超过10可以结束线程
bool isStop() {
for (size_t i = 0; i < max; i++)
{
if (bs[i]->data.count < 10) {
return false;
}
}
return true;
}
};
BoxDatas BoxDatas::my = BoxDatas();
//线程承载类
class MyThred
{
public:
int id;
std::mutex mtx;
std::condition_variable cv;
std::atomic_bool ready = false;
MyThred* p_next = nullptr;
//构造函数
MyThred(int id) {
this->id = id;
}
//数据处理函数
void funBox(BoxData* boxData) {
DWORD threadId = GetCurrentThreadId();
//如果已经有线程占用了,那么等待
std::unique_lock<std::mutex> lock(boxData->mtx);//这个锁的目标是: boxData->handelThread
if (boxData->handelThread != NULL) {
std::unique_lock<std::mutex> lock2(boxData->handelThread->mtx);//这个锁的目标是:handelThread->p_next
boxData->handelThread->p_next = this;
boxData->handelThread = this;
//lock2.unlock();
lock.unlock();
//cout <<"Thread id:"<< threadId <<" data Id:" << boxData->data.id << " wait \n";
print(boxData->data.id, "wait");
cv.wait(lock2);// 无条件激活等待的线程
//cv.wait(lock2, [this](){ return ready.load(); }); // 等待直到ready为true
}
else
{
boxData->handelThread = this;
lock.unlock();
}
//cout << "Thread id:" << threadId << " data Id :" << boxData->data.id << " exe \n";
print(boxData->data.id,"exe");
//数据处理
dataProcessing(boxData->data);
std::unique_lock<std::mutex> lock2(mtx);//这个锁的目标是:handelThread->p_next
//处理完成后需要调用等待激活的线程
if (p_next != nullptr) {
p_next->activeThread();
}
else
{
std::unique_lock<std::mutex> lock3(boxData->mtx);//这个锁的目标是: boxData->handelThread
boxData->handelThread = nullptr;
lock3.unlock();
}
lock2.unlock();
}
//数据处理逻辑
void dataProcessing(Data& data) {
//加一个延时填充线程执行占用的时间
//std::this_thread::sleep_for(std::chrono::seconds(5));
data.count++;
DWORD threadId = GetCurrentThreadId();
//cout << "Thread id:" << id << " data Id:" << data.id <<" data value:"<< data.count << " value \n";
print(data.id,"value", data.count);
}
void print(int dataId,std::string funType) {
DWORD threadId = GetCurrentThreadId();
std::unique_lock<std::mutex> lock(printmtx);
cout << "Thread id:" << threadId << " data Id:" << dataId << " " << funType << "\n";
lock.unlock();
}
void print(int dataId, std::string funType,int value) {
DWORD threadId = GetCurrentThreadId();
std::unique_lock<std::mutex> lock(printmtx);
cout << "Thread id:" << threadId << " data Id:" << dataId << " data value:"<< value <<" " << funType << "\n";
lock.unlock();
}
//此线程激活
void activeThread() {
ready = true;
cv.notify_one(); // 唤醒一个等待在cv上的线程(如果有的话)
}
//线程主函数
void mainThread() {
while (true)
{
for(BoxData* bd : BoxDatas::getMy().bs)
{
funBox(bd);
}
//如果完成了数据,那么退出
if (BoxDatas::getMy().isStop()) {
break;
}
}
}
//线程运行
std::thread run() {
return std::thread([this] {mainThread(); });
}
};
//入口函数
int main() {
std::thread threads[5];
//线程初始化
for (int i = 0; i < 5; i++)
{
MyThred thrend(i);
threads[i] = thrend.run();
}
//防止程序提取退出
for (size_t i = 0; i < 5; i++)
{
threads[i].join();
}
std::cout << "Hello from thread!\n";
return 0;
}
4.运行结果
Thread id:15512 data Id:0 exe
Thread id:19512 data Id:0 wait
Thread id:15512 data Id:0 data value:1 value
Thread id:9320 data Id:0 wait
Thread id:10556 data Id:0 wait
Thread id:15512 data Id:1 exe
Thread id:25516 data Id:0 wait
Thread id:15512 data Id:1 data value:1 value
Thread id:19512 data Id:0 exe
Thread id:15512 data Id:2 exe
Thread id:9320 data Id:0 exe
Thread id:19512 data Id:0 data value:2 value
Thread id:15512 data Id:2 data value:1 value
Thread id:9320 data Id:0 data value:3 value
Thread id:19512 data Id:1 wait
Thread id:10556 data Id:0 exe
Thread id:15512 data Id:3 exe
Thread id:9320 data Id:1 wait
Thread id:10556 data Id:0 data value:4 value
Thread id:15512 data Id:3 data value:1 value
Thread id:19512 data Id:1 exe
Thread id:25516 data Id:0 exe
Thread id:10556 data Id:1 wait
Thread id:19512 data Id:1 data value:2 value
Thread id:25516 data Id:0 data value:5 value
Thread id:9320 data Id:1 exe
Thread id:15512 data Id:4 exe
Thread id:10556 data Id:1 exe
Thread id:19512 data Id:2 wait
Thread id:9320 data Id:1 data value:3 value
Thread id:15512 data Id:4 data value:1 value
Thread id:10556 data Id:1 data value:4 value
Thread id:25516 data Id:1 wait
Thread id:19512 data Id:2 exe
Thread id:9320 data Id:2 wait
Thread id:19512 data Id:2 data value:2 value
Thread id:10556 data Id:2 wait
Thread id:15512 data Id:5 exe
Thread id:15512 data Id:5 data value:1 value
Thread id:25516 data Id:1 exe
Thread id:25516 data Id:1 data value:5 value
Thread id:9320 data Id:2 exe
Thread id:9320 data Id:2 data value:3 value
Thread id:19512 data Id:3 wait
Thread id:10556 data Id:2 exe
Thread id:15512 data Id:6 exe
Thread id:15512 data Id:6 data value:1 value
Thread id:10556 data Id:2 data value:4 value
Thread id:25516 data Id:2 wait
Thread id:19512 data Id:3 exe
Thread id:9320 data Id:3 wait
Thread id:19512 data Id:3 data value:2 value
Thread id:10556 data Id:3 wait
Thread id:15512 data Id:7 exe
Thread id:15512 data Id:7 data value:1 value
Thread id:25516 data Id:2 exe
Thread id:25516 data Id:2 data value:5 value
Thread id:9320 data Id:3 exe
Thread id:9320 data Id:3 data value:3 value
Thread id:19512 data Id:4 wait
Thread id:10556 data Id:3 exe
Thread id:10556 data Id:3 data value:4 value
Thread id:25516 data Id:3 wait
Thread id:19512 data Id:4 exe
Thread id:19512 data Id:4 data value:2 value
Thread id:9320 data Id:4 wait
Thread id:25516 data Id:3 exe
Thread id:25516 data Id:3 data value:5 value
Thread id:10556 data Id:4 wait
Thread id:15512 data Id:8 exe
Thread id:15512 data Id:8 data value:1 value
Thread id:19512 data Id:5 wait
Thread id:9320 data Id:4 exe
Thread id:9320 data Id:4 data value:3 value
Thread id:25516 data Id:4 wait
Thread id:10556 data Id:4 exe
Thread id:10556 data Id:4 data value:4 value
Thread id:15512 data Id:9 exe
Thread id:15512 data Id:9 data value:1 value
Thread id:19512 data Id:5 exe
Thread id:19512 data Id:5 data value:2 value
Thread id:9320 data Id:5 wait
Thread id:25516 data Id:4 exe
Thread id:10556 data Id:5 wait
Thread id:25516 data Id:4 data value:5 value
Thread id:19512 data Id:6 wait
Thread id:15512 data Id:0 wait
Thread id:9320 data Id:5 exe
Thread id:9320 data Id:5 data value:3 value
Thread id:25516 data Id:5 wait
Thread id:10556 data Id:5 exe
Thread id:10556 data Id:5 data value:4 value
Thread id:19512 data Id:6 exe
Thread id:9320 data Id:6 wait
Thread id:15512 data Id:0 exe
Thread id:19512 data Id:6 data value:2 value
Thread id:25516 data Id:5 exe
Thread id:10556 data Id:6 wait
Thread id:15512 data Id:0 data value:6 value
Thread id:25516 data Id:5 data value:5 value
Thread id:9320 data Id:6 exe
Thread id:19512 data Id:7 wait
Thread id:9320 data Id:6 data value:3 value
Thread id:10556 data Id:6 exe
Thread id:15512 data Id:1 wait
Thread id:10556 data Id:6 data value:4 value
Thread id:19512 data Id:7 exe
Thread id:25516 data Id:6 wait
Thread id:19512 data Id:7 data value:2 value
Thread id:15512 data Id:1 exe
Thread id:9320 data Id:7 wait
Thread id:15512 data Id:1 data value:6 value
Thread id:25516 data Id:6 exe
Thread id:25516 data Id:6 data value:5 value
Thread id:10556 data Id:7 wait
Thread id:9320 data Id:7 exe
Thread id:19512 data Id:8 wait
Thread id:9320 data Id:7 data value:3 value
Thread id:25516 data Id:7 wait
Thread id:15512 data Id:2 wait
Thread id:10556 data Id:7 exe
Thread id:10556 data Id:7 data value:4 value
Thread id:9320 data Id:8 wait
Thread id:19512 data Id:8 exe
Thread id:19512 data Id:8 data value:2 value
Thread id:25516 data Id:7 exe
Thread id:25516 data Id:7 data value:5 value
Thread id:15512 data Id:2 exe
Thread id:15512 data Id:2 data value:6 value
Thread id:10556 data Id:8 wait
Thread id:9320 data Id:8 exe
Thread id:9320 data Id:8 data value:3 value
Thread id:19512 data Id:9 wait
Thread id:15512 data Id:3 wait
Thread id:25516 data Id:8 wait
Thread id:19512 data Id:9 exe
Thread id:19512 data Id:9 data value:2 value
Thread id:15512 data Id:3 exe
Thread id:9320 data Id:9 wait
Thread id:10556 data Id:8 exe
Thread id:10556 data Id:8 data value:4 value
Thread id:25516 data Id:8 exe
Thread id:19512 data Id:0 wait
Thread id:15512 data Id:3 data value:6 value
Thread id:25516 data Id:8 data value:5 value
Thread id:9320 data Id:9 exe
Thread id:10556 data Id:9 wait
Thread id:9320 data Id:9 data value:3 value
Thread id:19512 data Id:0 exe
Thread id:19512 data Id:0 data value:7 value
Thread id:15512 data Id:4 wait
Thread id:10556 data Id:9 exe
Thread id:25516 data Id:9 wait
Thread id:10556 data Id:9 data value:4 value
Thread id:19512 data Id:1 wait
Thread id:9320 data Id:0 wait
Thread id:15512 data Id:4 exe
Thread id:15512 data Id:4 data value:6 value
Thread id:10556 data Id:0 wait
Thread id:25516 data Id:9 exe
Thread id:9320 data Id:0 exe
Thread id:19512 data Id:1 exe
Thread id:19512 data Id:1 data value:7 value
Thread id:25516 data Id:9 data value:5 value
Thread id:9320 data Id:0 data value:8 value
Thread id:15512 data Id:5 wait
Thread id:10556 data Id:0 exe
Thread id:10556 data Id:0 data value:9 value
Thread id:19512 data Id:2 wait
Thread id:9320 data Id:1 wait
Thread id:25516 data Id:0 wait
Thread id:19512 data Id:2 exe
Thread id:15512 data Id:5 exe
Thread id:9320 data Id:1 exe
Thread id:10556 data Id:1 wait
Thread id:19512 data Id:2 data value:7 value
Thread id:15512 data Id:5 data value:6 value
Thread id:9320 data Id:1 data value:8 value
Thread id:25516 data Id:0 exe
Thread id:25516 data Id:0 data value:10 value
Thread id:19512 data Id:3 wait
Thread id:10556 data Id:1 exe
Thread id:10556 data Id:1 data value:9 value
Thread id:15512 data Id:6 wait
Thread id:25516 data Id:1 wait
Thread id:9320 data Id:2 wait
Thread id:15512 data Id:6 exe
Thread id:15512 data Id:6 data value:6 value
Thread id:25516 data Id:1 exe
Thread id:25516 data Id:1 data value:10 value
Thread id:19512 data Id:3 exe
Thread id:10556 data Id:2 wait
Thread id:19512 data Id:3 data value:7 value
Thread id:9320 data Id:2 exe
Thread id:15512 data Id:7 wait
Thread id:9320 data Id:2 data value:8 value
Thread id:10556 data Id:2 exe
Thread id:25516 data Id:2 wait
Thread id:10556 data Id:2 data value:9 value
Thread id:15512 data Id:7 exe
Thread id:19512 data Id:4 wait
Thread id:15512 data Id:7 data value:6 value
Thread id:25516 data Id:2 exe
Thread id:25516 data Id:2 data value:10 value
Thread id:9320 data Id:3 wait
Thread id:19512 data Id:4 exe
Thread id:10556 data Id:3 wait
Thread id:19512 data Id:4 data value:7 value
Thread id:25516 data Id:3 wait
Thread id:15512 data Id:8 wait
Thread id:9320 data Id:3 exe
Thread id:9320 data Id:3 data value:8 value
Thread id:19512 data Id:5 wait
Thread id:10556 data Id:3 exe
Thread id:15512 data Id:8 exe
Thread id:25516 data Id:3 exe
Thread id:9320 data Id:4 wait
Thread id:10556 data Id:3 data value:9 value
Thread id:10556 data Id:4 wait
Thread id:25516 data Id:3 data value:10 value
Thread id:19512 data Id:5 exe
Thread id:15512 data Id:8 data value:6 value
Thread id:9320 data Id:4 exe
Thread id:9320 data Id:4 data value:8 value
Thread id:19512 data Id:5 data value:7 value
Thread id:25516 data Id:4 wait
Thread id:10556 data Id:4 exe
Thread id:15512 data Id:9 wait
Thread id:10556 data Id:4 data value:9 value
Thread id:19512 data Id:6 wait
Thread id:9320 data Id:5 wait
Thread id:25516 data Id:4 exe
Thread id:10556 data Id:5 wait
Thread id:25516 data Id:4 data value:10 value
Thread id:15512 data Id:9 exe
Thread id:15512 data Id:9 data value:6 value
Thread id:19512 data Id:6 exe
Thread id:25516 data Id:5 wait
Thread id:9320 data Id:5 exe
Thread id:9320 data Id:5 data value:8 value
Thread id:10556 data Id:5 exe
Thread id:10556 data Id:5 data value:9 value
Thread id:19512 data Id:6 data value:7 value
Thread id:15512 data Id:0 wait
Thread id:25516 data Id:5 exe
Thread id:9320 data Id:6 wait
Thread id:25516 data Id:5 data value:10 value
Thread id:19512 data Id:7 wait
Thread id:10556 data Id:6 wait
Thread id:15512 data Id:0 exe
Thread id:15512 data Id:0 data value:11 value
Thread id:25516 data Id:6 wait
Thread id:9320 data Id:6 exe
Thread id:9320 data Id:6 data value:8 value
Thread id:19512 data Id:7 exe
Thread id:19512 data Id:7 data value:7 value
Thread id:10556 data Id:6 exe
Thread id:10556 data Id:6 data value:9 value
Thread id:15512 data Id:1 wait
Thread id:25516 data Id:6 exe
Thread id:25516 data Id:6 data value:10 value
Thread id:9320 data Id:7 wait
Thread id:10556 data Id:7 wait
Thread id:19512 data Id:8 wait
Thread id:9320 data Id:7 exe
Thread id:9320 data Id:7 data value:8 value
Thread id:10556 data Id:7 exe
Thread id:25516 data Id:7 wait
Thread id:15512 data Id:1 exe
Thread id:15512 data Id:1 data value:11 value
Thread id:19512 data Id:8 exe
Thread id:19512 data Id:8 data value:7 value
Thread id:10556 data Id:7 data value:9 value
Thread id:9320 data Id:8 wait
Thread id:25516 data Id:7 exe
Thread id:15512 data Id:2 wait
Thread id:25516 data Id:7 data value:10 value
Thread id:10556 data Id:8 wait
Thread id:19512 data Id:9 wait
Thread id:9320 data Id:8 exe
Thread id:9320 data Id:8 data value:8 value
Thread id:25516 data Id:8 wait
Thread id:15512 data Id:2 exe
Thread id:15512 data Id:2 data value:11 value
Thread id:10556 data Id:8 exe
Thread id:10556 data Id:8 data value:9 value
Thread id:19512 data Id:9 exe
Thread id:19512 data Id:9 data value:7 value
Thread id:9320 data Id:9 wait
Thread id:25516 data Id:8 exe
Thread id:25516 data Id:8 data value:10 value
Thread id:15512 data Id:3 wait
Thread id:19512 data Id:0 wait
Thread id:10556 data Id:9 wait
Thread id:15512 data Id:3 exe
Thread id:15512 data Id:3 data value:11 value
Thread id:19512 data Id:0 exe
Thread id:19512 data Id:0 data value:12 value
Thread id:9320 data Id:9 exe
Thread id:9320 data Id:9 data value:8 value
Thread id:25516 data Id:9 wait
Thread id:10556 data Id:9 exe
Thread id:10556 data Id:9 data value:9 value
Thread id:15512 data Id:4 wait
Thread id:9320 data Id:0 wait
Thread id:19512 data Id:1 wait
Thread id:15512 data Id:4 exe
Thread id:15512 data Id:4 data value:11 value
Thread id:9320 data Id:0 exe
Thread id:9320 data Id:0 data value:13 value
Thread id:25516 data Id:9 exe
Thread id:25516 data Id:9 data value:10 value
Thread id:10556 data Id:0 wait
Thread id:19512 data Id:1 exe
Thread id:19512 data Id:1 data value:12 value
Thread id:15512 data Id:5 wait
Thread id:10556 data Id:0 exe
Thread id:10556 data Id:0 data value:14 value
Thread id:9320 data Id:1 wait
Thread id:15512 data Id:5 exe
Thread id:15512 data Id:5 data value:11 value
Thread id:19512 data Id:2 wait
Thread id:9320 data Id:1 exe
Thread id:9320 data Id:1 data value:13 value
Thread id:10556 data Id:1 wait
Thread id:19512 data Id:2 exe
Thread id:19512 data Id:2 data value:12 value
Thread id:15512 data Id:6 wait
Thread id:10556 data Id:1 exe
Thread id:10556 data Id:1 data value:14 value
Thread id:9320 data Id:2 wait
Thread id:15512 data Id:6 exe
Thread id:15512 data Id:6 data value:11 value
Thread id:19512 data Id:3 wait
Thread id:9320 data Id:2 exe
Thread id:9320 data Id:2 data value:13 value
Thread id:10556 data Id:2 wait
Thread id:19512 data Id:3 exe
Thread id:19512 data Id:3 data value:12 value
Thread id:15512 data Id:7 wait
Thread id:10556 data Id:2 exe
Thread id:10556 data Id:2 data value:14 value
Thread id:9320 data Id:3 wait
Thread id:15512 data Id:7 exe
Thread id:15512 data Id:7 data value:11 value
Thread id:19512 data Id:4 wait
Thread id:9320 data Id:3 exe
Thread id:9320 data Id:3 data value:13 value
Thread id:10556 data Id:3 wait
Thread id:19512 data Id:4 exe
Thread id:19512 data Id:4 data value:12 value
Thread id:15512 data Id:8 wait
Thread id:10556 data Id:3 exe
Thread id:10556 data Id:3 data value:14 value
Thread id:9320 data Id:4 wait
Thread id:15512 data Id:8 exe
Thread id:15512 data Id:8 data value:11 value
Thread id:19512 data Id:5 wait
Thread id:9320 data Id:4 exe
Thread id:9320 data Id:4 data value:13 value
Thread id:10556 data Id:4 wait
Thread id:19512 data Id:5 exe
Thread id:19512 data Id:5 data value:12 value
Thread id:15512 data Id:9 wait
Thread id:10556 data Id:4 exe
Thread id:10556 data Id:4 data value:14 value
Thread id:9320 data Id:5 wait
Thread id:15512 data Id:9 exe
Thread id:15512 data Id:9 data value:11 value
Thread id:19512 data Id:6 wait
Thread id:9320 data Id:5 exe
Thread id:9320 data Id:5 data value:13 value
Thread id:10556 data Id:5 wait
Thread id:19512 data Id:6 exe
Thread id:19512 data Id:6 data value:12 value
Thread id:9320 data Id:6 wait
Thread id:10556 data Id:5 exe
Thread id:10556 data Id:5 data value:14 value
Thread id:19512 data Id:7 wait
Thread id:9320 data Id:6 exe
Thread id:10556 data Id:6 wait
Thread id:9320 data Id:6 data value:13 value
Thread id:19512 data Id:7 exe
Thread id:19512 data Id:7 data value:12 value
Thread id:9320 data Id:7 wait
Thread id:10556 data Id:6 exe
Thread id:10556 data Id:6 data value:14 value
Thread id:19512 data Id:8 wait
Thread id:9320 data Id:7 exe
Thread id:9320 data Id:7 data value:13 value
Thread id:10556 data Id:7 wait
Thread id:19512 data Id:8 exe
Thread id:19512 data Id:8 data value:12 value
Thread id:9320 data Id:8 wait
Thread id:10556 data Id:7 exe
Thread id:10556 data Id:7 data value:14 value
Thread id:19512 data Id:9 wait
Thread id:9320 data Id:8 exe
Thread id:9320 data Id:8 data value:13 value
Thread id:10556 data Id:8 wait
Thread id:19512 data Id:9 exe
Thread id:19512 data Id:9 data value:12 value
Thread id:9320 data Id:9 wait
Thread id:10556 data Id:8 exe
Thread id:10556 data Id:8 data value:14 value
Thread id:10556 data Id:9 wait
Thread id:9320 data Id:9 exe
Thread id:9320 data Id:9 data value:13 value
Thread id:10556 data Id:9 exe
Thread id:10556 data Id:9 data value:14 value
Hello from thread!