C++ 使用c++;构建生产者-消费者模式的打包任务
我正在尝试创建一个生产者-消费者模式 代码如下:C++ 使用c++;构建生产者-消费者模式的打包任务,c++,multithreading,packaged-task,C++,Multithreading,Packaged Task,我正在尝试创建一个生产者-消费者模式 代码如下: test\u thread9\u producer1和test\u thread9\u producer2将任务推送到队列中 和test\u thread9\u consumer1从队列中检索要执行的任务 但是,当运行test\u thread9时,它会正确执行任务,但完成时出现调试错误:已调用abort。我不知道为什么?有人能帮我更好地理解打包的任务吗 第二个问题:消费者正在运行,而(1)循环,我想不出优雅的方式 当两个生产者完成将所有任务推送
test\u thread9\u producer1
和test\u thread9\u producer2
将任务推送到队列中
和test\u thread9\u consumer1
从队列中检索要执行的任务
但是,当运行test\u thread9
时,它会正确执行任务,但完成时出现调试错误:已调用abort。我不知道为什么?有人能帮我更好地理解打包的任务吗
第二个问题:消费者正在运行,而(1)
循环,我想不出优雅的方式
当两个生产者完成将所有任务推送到队列中并且test\u thread9\u consumer1
完成执行队列中的所有任务时,允许test\u thread9\u consumer1
退出。谁能给我一些建议吗
void test_thread9()
{
std::thread t1(test_thread9_producer1);
std::thread t2(test_thread9_producer2);
std::thread t3(test_thread9_consumer1);
t1.join();
t2.join();
t3.join();
}
std::deque<std::packaged_task<int()>>task_q;
std::mutex lock9;
int factial_calc2(int in)
{
int ret = 1;
for (int i = in; i > 1; i--)
{
ret = ret*i;
}
std::lock_guard<std::mutex> locker(lock9);
std::cout << "input is " << in << "result is " << ret << std::endl;
return ret;
}
void test_thread9_producer1()
{
for (int i = 0; i < 10; i = i + 2)
{
std::lock_guard<std::mutex> locker(lock9);
std::packaged_task<int()> t1(std::bind(factial_calc2, i));
task_q.push_back(std::move(t1));
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
void test_thread9_producer2()
{
for (int i = 1; i < 10; i = i + 2)
{
std::lock_guard<std::mutex> locker(lock9);
std::packaged_task<int()> t1(std::bind(factial_calc2, i));
task_q.push_back(std::move(t1));
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
void test_thread9_consumer1()
{
std::packaged_task<int()>t;
while (1)
{
{
std::lock_guard<std::mutex> locker(lock9);
if (!task_q.empty())
{
t = std::move(task_q.front());
task_q.pop_front();
}
}
t();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
void test_thread9()
{
标准:螺纹t1(测试螺纹9螺纹1);
标准:螺纹t2(测试螺纹9螺纹产品2);
标准:螺纹t3(测试螺纹9螺纹1);
t1.join();
t2.连接();
t3.join();
}
std::dequetask_q;
std::互斥锁9;
内部模拟计算(内部模拟)
{
int-ret=1;
对于(int i=in;i>1;i--)
{
ret=ret*i;
}
标准:锁柜(锁9);
std::cout为什么会崩溃?
如果您的使用者线程发现一个空队列,它仍将尝试执行打包的任务,尽管它没有移动。这是UB,因此是运行时错误
您可以通过检查打包的任务是否为:
无效试验螺纹9产品()
{
为什么它会崩溃?
如果您的使用者线程发现一个空队列,它仍将尝试执行打包的任务,尽管它没有移动。这是UB,因此是运行时错误
您可以通过检查打包的任务是否为:
无效试验螺纹9产品()
{
在调试器中运行时,程序在哪里停止?在调试器中运行时,程序在哪里停止?
while (1)
{
std::packaged_task<int()>t; // to make sure that valid() checks this iteration
{
...
}
if (t.valid())
t(); // execute only if it's a valid task
...
}
std::atomic<int>finished{0}; // count the producers that are finished
...
void test_thread9_consumer1()
{
bool nothing_to_do{false};
while (!nothing_to_do && finished<2)
{
...
nothing_to_do=task_q.empty(); // in the lock protected section
if (!nothing_to_do)
...
}
}
void test_thread9_consumer1()
{
std::packaged_task<int()>t;
while (1)
{
{
std::lock_guard<std::mutex> locker(lock9);
if (!task_q.empty())
{
t = std::move(task_q.front());
task_q.pop_front();
}
}
t();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
std::packaged_task<int()>t;
while (1)
{
if (!task_q.empty())
t = std::move(task_q.front());
t();
}
void test_thread9_consumer1()
{
std::packaged_task<int()>t;
while (1)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
{
std::lock_guard<std::mutex> locker(lock9);
if (task_q.empty())
continue;
t = std::move(task_q.front());
task_q.pop_front();
}
t();
}
}
void test_thread9()
{
std::thread t1(test_thread9_producer1);
std::thread t2(test_thread9_producer2);
g_producing = true;
std::thread t3(test_thread9_consumer1);
t1.join();
t2.join();
g_producing = false;
t3.join();
}
std::deque<std::packaged_task<int()>>task_q;
std::mutex lock9;
int factial_calc2(int in)
{
int ret = 1;
for (int i = in; i > 1; i--)
{
ret = ret*i;
}
std::lock_guard<std::mutex> locker(lock9);
std::cout << "input is " << in << "result is " << ret << std::endl;
return ret;
}
void test_thread9_producer1()
{
for (int i = 0; i < 10; i = i + 2)
{
std::lock_guard<std::mutex> locker(lock9);
std::packaged_task<int()> t1(std::bind(factial_calc2, i));
task_q.push_back(std::move(t1));
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
void test_thread9_producer2()
{
for (int i = 1; i < 10; i = i + 2)
{
std::lock_guard<std::mutex> locker(lock9);
std::packaged_task<int()> t1(std::bind(factial_calc2, i));
task_q.push_back(std::move(t1));
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
void test_thread9_consumer1()
{
std::packaged_task<int()>t;
for (;;)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
{
std::lock_guard<std::mutex> locker(lock9);
if (task_q.empty()) {
if (!g_producing)
break;
continue;
}
t = std::move(task_q.front());
task_q.pop_front();
}
t();
}
}