#include <thread>
#include <mutex>
#include <condition_variable>
#include <list>
#include <iostream>
#include <string>
#include <vector>
class Work
{
Work()=default;
virtual void dosomething() = 0;
};
class WorkInfo : Work
{
public:
virtual void doTask() = 0;
void dosomething()final
{}
~WorkInfo(){}
};
class goods
{
public:
goods():something(nullptr)
{}
goods(const goods & t)
{
if( t.something != nullptr)
{
something = new std::vector<std::string> (*t.something);
}
std::cout << "copy" << std::endl;
}
goods(goods && t)
{
something = t.something;
t.something = nullptr;
std::cout << "move" << std::endl;
}
goods(std::vector<std::string> things)
{
something = new std::vector<std::string>(things);
std::cout << "goods string " << (*something)[0] << std::endl;
}
~goods()
{
std::cout << "~GOODS" << std::endl;
if (something)
{
delete something;
}
something = nullptr;
}
private:
std::vector<std::string> *something;
};
class Task final : WorkInfo
{
public:
Task()=default;
Task(int taskId,goods & someGoods):id(taskId),something(someGoods)
{
std::cout << "lvalue" << std::endl;
}
Task(int taskId,goods && someGoods):id(taskId),something(someGoods)
{
std::cout << "rvalue" << std::endl;
}
Task(const Task && t) : id(t.id)
{
std::cout << this->id << std::endl;
}
void doTask()override
{
std::cout << "handle a task, taskId: " << id << ", threadID: " << std::this_thread::get_id() << std::endl;
}
~Task()
{}
private:
int id;
goods something;
};
std::mutex mymutex;
std::list<Task*> tasks;
std::condition_variable mycv;
void* consumer_thread()
{
Task* pTask = NULL;
while (true)
{
std::unique_lock<std::mutex> guard(mymutex);
while (tasks.empty())
{
mycv.wait(guard);
}
pTask = tasks.front();
tasks.pop_front();
if (pTask == NULL)
continue;
pTask->doTask();
delete pTask;
pTask = NULL;
}
return NULL;
}
void* producer_thread(goods && vstr)
{
int taskID = 0;
Task* pTask1 = NULL;
Task* pTask2 = NULL;
while (true)
{
pTask1 = new Task(taskID,vstr);
pTask2 = new Task(++taskID,std::forward<goods>(vstr));
{
std::lock_guard<std::mutex> guard(mymutex);
tasks.push_back(pTask1);
tasks.push_back(pTask2);
std::cout << "produce a task, taskID: " << taskID << ", threadID: " << std::this_thread::get_id() << std::endl;
}
mycv.notify_one();
++taskID;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return NULL;
}
int main()
{
std::vector<std::string> vstr{"goodsA","goodsA","..."};
std::thread consumer1(consumer_thread);
std::thread consumer2(consumer_thread);
std::thread producer1(producer_thread,goods(vstr));
producer1.join();
consumer1.join();
consumer2.join();
return 0;
}
std::mutex mymutex;
std::condition_variable mycv;
consumer()
{
std::unique_lock<std::mutex> guard(mymutex);
while( xxx )
mycv.wait(guard);
}
producer()
{
mycv.notify_one();
}