假设我们有两个 worker 。每个 worker 都有一个 0 和 1 的 id。还假设我们一直有工作到达,每个工作也有一个标识符 0 或 1 指定哪个 worker 必须做这个工作。
我想创建 2 个线程,它们最初是锁定的,然后当两个作业到达时,解锁它们,每个线程都完成它们的工作,然后再次锁定它们,直到其他作业到达。
我有以下代码:
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
struct job{
thread jobThread;
mutex jobMutex;
};
job jobs[2];
void executeJob(int worker){
while(true){
jobs[worker].jobMutex.lock();
//do some job
}
}
void initialize(){
int i;
for(i=0;i<2;i++){
jobs[i].jobThread = thread(executeJob, i);
}
}
int main(void){
//initialization
initialize();
int buffer[2];
int bufferSize = 0;
while(true){
//jobs arrive here constantly,
//once the buffer becomes full,
//we unlock the threads(workers) and they start working
bufferSize = 2;
if(bufferSize == 2){
for(int i = 0; i<2; i++){
jobs[i].jobMutex.unlock();
}
}
break;
}
}
我几天前开始使用 std::thread,我不确定为什么,但 Visual Studio 给我一个错误,说 abort() 已被调用。我相信缺少一些东西,但是由于我的无知,我无法弄清楚是什么。
我希望这段代码实际上能够
初始化两个线程然后加锁
在 main 函数中解锁两个线程,这两个线程将完成它们的工作(在本例中什么都不做)然后它们将再次被锁定。
但它却给了我一个错误。我做错了什么?
提前致谢!
最佳答案
为此,您可以使用 boost 的线程池类。 它高效且经过充分测试。开源库,而不是你编写新的并稳定它。
http://threadpool.sourceforge.net/
main()
{
pool tp(2); //number of worker threads-currently its 2.
// Add some tasks to the pool.
tp.schedule(&first_task);
tp.schedule(&second_task);
}
void first_task()
{
...
}
void second_task()
{
...
}
注意:
针对您的示例的建议: 您不需要为每个线程都有单独的互斥对象。单个互斥对象锁本身将在所有线程之间进行同步。您在 executejob 函数中锁定了一个线程的互斥锁,而没有解锁另一个线程正在使用不同的互斥锁对象调用锁,从而导致死锁或未定义的行为。
此外,由于您在 whileloop 内调用 mutex.lock() 而不解锁,同一个线程试图用相同的互斥对象锁定自身,最终导致未定义的行为。
如果您不需要并行执行线程,您可以在 executejob 函数中使用一个全局互斥对象来锁定和解锁。
mutex m;
void executeJob(int worker)
{
m.lock();
//do some job
m.unlock();
}
如果您想并行执行作业,请按照我之前的建议使用 boost threadpool。
关于c++ - (C++ 线程): Creating worker threads that will be listening to jobs and executing them concurrently when wanted,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15976857/