在不同的线程中执行 lambda 函数
Posted
技术标签:
【中文标题】在不同的线程中执行 lambda 函数【英文标题】:execute a lambda function in different thread 【发布时间】:2021-09-26 23:29:07 【问题描述】:由于固定要求,我需要在特定线程中执行一些代码,然后返回结果。同时应该阻塞启动该操作的主线程。
void background_thread()
while(1)
request.lock();
g_lambda();
response.unlock();
request.unlock();
void mainthread()
...
g_lambda = []()...;
request.unlock();
response.lock();
request.lock();
...
这应该可行。但这给我们留下了一个大问题:后台线程需要从响应互斥锁开始,而主线程需要从请求互斥锁开始......
我们怎样才能做到这一点?我想不出什么好办法。这难道不是一种反模式吗?
【问题讨论】:
这个想法无论如何都是错误的。主线程执行request.unlock()
后,后台线程可能会循环多次,多次执行lambda并解锁未锁定的响应互斥锁。
听起来你可能会更好地使用两个生产者-消费者队列:一个用于生成由辅助线程运行的 lambdas/任务的主线程,另一个用于辅助线程产生的结果和由主线程读取/处理。但是,正如所展示的那样,它确实看起来像一个 xy 问题。
请显示minimal reproducible example。 std::thread t(g_lambda); t.join();
还不够吗(尽管毫无意义)?
user253751 是对的。嗯.... @AlanBirtles 不,它必须是一个特定的线程,而不仅仅是任何后台线程。太糟糕了。我会考虑更多,并研究消费者队列的替代方案......谢谢。
【参考方案1】:
将任务传递给后台线程可以通过生产者-消费者队列来完成。不依赖于第三方库的简单 C++11 实现将具有 std::condition_variable
,它由后台线程等待并由主线程通知,std::queue
任务和std::mutex
来保护这些。
可以通过std::promise
/std::future
将结果返回到主线程。最简单的方法是将std::packaged_task
作为队列对象,这样主线程创建packaged_task
,将其放入队列,通知condition_variable
并等待packaged_task
的未来。
如果您要从一个线程一次创建一个任务,则实际上不需要std::queue
- 只需一个std::unique_ptr<std::packaged_task>>
就足够了。队列增加了同时添加许多后台任务的灵活性。
【讨论】:
谢谢!一个问题:如果我知道我总是阻塞主线程,我可以删除 std::packaged_task 并直接使用 std::function 吗?返回值将使用相同的 condition_variable 发回信号。与 packaged_task + future 相比会有任何(性能)优势吗? 你可以。虽然我更喜欢不同的条件变量。可能会有性能优势。以上是关于在不同的线程中执行 lambda 函数的主要内容,如果未能解决你的问题,请参考以下文章