我正在学习C ++ 11中新的多线程技术。我在网上阅读的几乎所有教程都教授如何启动执行函数的新线程(或几个线程),如何在以后加入(或分离)线程(或线程)以及如何使用{{1来避免竞争条件等等。
但是我没有看到它们中的任何一个显示如何让一个线程在程序的不同部分执行多个函数。问题是,使用C ++ 11线程,是否可以实现以下目标?如果是这样,怎么样? (举一个例子会很棒)。
mutex
而且,如果我想将上面的void func1(std::vector<int> & data1){ ... }
void func2(std::vector<int> & data2){ ... }
// main function version I
int main(){
std::vector<int> data1;
// prepare data1 for func1;
std::thread t1(func1, std::ref(data1));
std::vector<int> data2;
// prepare data2 for func2;
if (func1 in t1 is done){
t1(func2, std::ref(data2));
}
t1.join();
return 0;
}
函数体放入循环中,如下所示。可能吗?如果是这样,怎么样?
main
答案 0 :(得分:1)
来自cplusplus.com的参考:
默认构造函数构造一个不代表任何执行线程的线程对象。
因此GetFiles()
根本没有定义可执行线程。创建线程时必须提供线程函数,之后无法设置。
对于主要功能版本I,您必须创建两个线程。如下所示:
std::thread t
同样,你可以把它们放在一个循环中,它可以为你提供主要功能版本II 。
答案 1 :(得分:1)
C ++ 11线程是用于编写真实库的原语。它们不容易使用。你应该把它们包起来。
类似的东西:
struct tasks {
std::mutex m;
std::condition_variable v;
std::vector<std::packaged_task<void>> work;
std::vector<std::future<void>> finished;
void operator()(){
while(true){
std::packaged_task<void> f;
{
std::unique_lock<std::mutex> l(m);
if (work.empty()){
v.wait(l,[&]{return !work.empty();});
}
f = std::move(work.front());
work.pop_front();
}
if (!f.valid()) return;
f();
}
}
std::future<void> do(std::function<void()> f){
std::packaged_task<void> p(f);
auto r=p.get_future();
{
std::unique_lock<std::mutex> l(m);
work.push_back(std::move(p));
v.notify_one();
}
return r;
}
void start(){
finished.push_back(std::async(std::launch_policy::async,
std::ref(*this)));
}
~tasks(){
std::unique_lock<std::mutex> l(m);
for(auto&&unused:finished){
work.push_back({});
}
v.notify_all();
}
};
使用看起来像:
int main(){
tasks t;
t.start();
t.do([]({std::cout<<"hello ";});
t.do([]({std::cout<<"world\n";});
}
如果您想知道任务何时完成,请检查将来的do
返回。
写在手机上,没有编译,可能充满了错别字和错误,但还有一个起点。
不支持提前中止。易于编写abaondon
清空work
。
我怀疑支持多个消费者(workwe线程)。在兼容系统上,dtor将等待所有线程完成排队的作业。不是在MSVC2013上。