在C 03中,我使用了带有自建线程池的pthon,它总是保持几个线程运行(因为pthread_create
很慢),这样我就可以为小任务启动线程,而无需考虑性能问题。
现在,在C11中,我们有d::线程。我想标准没有说明具体的实现,所以我的问题是关于标准库实现的。他们通常选择构建std::线程
s很便宜的池方法(例如,在posx上不调用pthread_create
),还是std::线程
只是一个包装器?
换句话说,在C11中仍然推荐线程池,或者我应该在需要时创建一个std::线程
,并将性能留给标准库?
std::thread
在抽象成本方面应该非常便宜,这是低级的东西。据我所知,标准库实现可能只会尽可能紧密地包装底层操作系统机制,这样您就可以假设线程创建的开销是相似的或等效的。
我不知道有什么具体的实现,但从阅读C并发的实际应用中,我的间接理解是,标准建议他们使用最有效的实用方法。作者当然似乎认为,与DIY相比,成本或多或少可以忽略不计。
该库在概念上类似于Boost,因此我认为使用Boost实现得出一些结论不会太牵强。
基本上,我认为你的问题没有直接的答案,因为它没有被指定。虽然在我看来,我们更有可能看到非常薄的包装器实现,但我不认为库编写者会被限制使用线程池,如果它提供效率优势的话。
std::thread是一个执行线程。时期它来自哪里、如何实现、是否有“实际”线程池等等,都与标准无关。只要它像线程一样工作,它就可以是std::thread
。
现在,很有可能std::thread
是一个真实的操作系统线程,而不是从线程池或其他任何地方提取的东西。但从理论上讲,C11确实允许将std::thread
实现为从池中提取的东西。
通常,std::thread
应该是底层系统原语的最小包装器。例如,如果您在pthread
平台上,可以使用以下程序测试,无论创建多少线程,它们都是使用唯一的pthread_t
ID创建的(这意味着它们是动态创建的,不是从线程池借用的):
#include <assert.h>
#include <mutex>
#include <set>
#include <thread>
#include <vector>
#include <pthread.h>
int main() {
std::vector<std::thread> workers;
std::set<long long> thread_ids;
std::mutex m;
const int n = 1024;
for (int i = 0; i < n; ++i) {
workers.push_back(std::thread([&] {
std::lock_guard<std::mutex> lock(m);
thread_ids.insert(pthread_self());
}));
}
for (auto& worker : workers) {
worker.join();
}
assert(thread_ids.size() == n);
return 0;
}
所以线程池仍然是非常有意义的。也就是说,我看过一个视频,其中C委员会成员讨论了关于std::async
(IIRC)的线程池,但我现在找不到它。
我对最新gcc中基于pthread和Ubuntu开发环境的线程的互斥锁和消息传递的性能感兴趣。一个很好的通用问题是用餐哲学家,每个哲学家使用lh和rh叉子与左右手邻居共享。我把哲学家的数量增加到99个,让我的四核处理器保持忙碌。 上面的代码允许我的哲学家尝试抓住他们需要的两个叉子。 上面的代码监控我的哲学家的进食或思考进度,这取决于他们是否能够保留这两个叉子。 在所有哲学家尝试自由选择后,等待所有
我在Ubuntu13.04桌面上运行这个非常简单的程序,但是如果我注释掉sleep_for一行,它会在从main打印cout后挂起。有人能解释为什么吗?据我所知,main是一个线程,t是另一个线程,在本例中,互斥体管理共享cout对象的同步。
我在使用std::result_of、decltype和std::function时遇到了很多麻烦 使用可变模板。 我有以下功能- 下一节课呢 我希望类中有一个成员保存lambda表达式, 为此我需要一个d::f。 我的问题是我如何正确地定义d::f。 这个类的用例如下所示- 现在我有了T=int u-cdecl(int,int,int)和Args=(int-1,int-2,int-3) 因此,我
令我惊讶的是,已经完成执行但尚未加入的C11std::thread对象仍然被视为活动执行线程。下面的代码示例说明了这一点(基于Xubuntu 13.03和G4.7.3构建)。有人知道C 11标准是否提供了一种检测std::thread对象是否仍在积极运行代码的方法吗?
假设我有std::vector和两个线程。 第一个线程正在处理擦除函数,而第二个线程在for循环中 这种情况是线程安全的吗? 第二个线程会继续运行还是抛出异常?