用c ++命令多线程输出

时间:2012-07-31 18:36:25

标签: c++ multithreading

这个简单示例中的一个如何保证

   a->push_back(i)

按线程启动的顺序发生?所以内容将是{1,2,3}。

#include <vector>
#include <thread>

void do_stuf(int i,std::vector<int> * a)
{
    //do very long stuff
    a->push_back(i);
}


int main()
{
    std::vector<int> tmp;
    std::thread t1(do_stuf,1,&tmp);
    std::thread t2(do_stuf,2,&tmp);
    std::thread t3(do_stuf,3,&tmp);

    t1.join();
    t2.join();
    t3.join();
}

5 个答案:

答案 0 :(得分:5)

一种方法是将线程指针或引用传递给您希望它们存储结果的位置(并确保它仍然为线程生命周期分配),如下所示:

void do_stuf(int i, int* a)
{
    //do very long stuff
    *a = i;
}


int main()
{
    std::vector<int> tmp(3);
    std::thread t1(do_stuf,1,&tmp[0]);
    std::thread t2(do_stuf,2,&tmp[1]);
    std::thread t3(do_stuf,3,&tmp[2]);

    t1.join();
    t2.join();
    t3.join();
}

从你的例子中不清楚你想要实现什么,但你有没有看过std :: promise和std :: future并想出他们做了什么?它们可能就是你想要的。

(在这种情况下,vector :: push_back的问题在于它不是线程安全的。如果两个push_backs执行重叠,它可能会覆盖相同的元素,或者它可能会重新分配数组移动所有元素的存储位置。)

答案 1 :(得分:0)

你可以通过几种方式来解决这个问题。如果你不关心它们完成的顺序,只关注结果的顺序,用任务id及其结果推送一个对象,然后按任务id对对象进行排序,并在完成所有操作后打印。

如果您确实希望他们在上一个任务完成之前不报告,您需要等待上一个任务。

答案 2 :(得分:0)

对不起,我错过了“//做很长的事”。如果在长动作结束时必须按特定顺序执行特殊操作,则可以简单地将该代码放在3个线程的连接后面。

如果必须由该特定线程执行此操作,则可以使用受互斥锁和条件变量保护的共享计数器来表示此计数器已更改。更改计数器时,必须通知所有服务员,因为需要唤醒特定的线程。在函数结束时,函数等待计数器具有特定于线程的值。第一个线程正在等待初始值,执行它的操作,递增计数器。第二个线程正在等待计数器成为第二个值等。

答案 3 :(得分:-1)

您可以进行同步&#39;当线程长进程按照它们被调度的顺序完成时,回退。

旁注,如果你想在多线程世界中使用push_back,我会使用list而不是vector,list会保留除被删除元素之外的所有东西的迭代器......

答案 4 :(得分:-1)

如上所述,插入可以任意排序。为了确保您想要的订单,您基本上需要一个票务系统,其中线程休眠/旋转,直到请求它们的票号。在较高级别,这意味着您将额外的信息传递给每个线程(其票号),具有作为请求的票证ID的全局共享值,并且线程代码具有一些代码以确保不执行任何插入直到全局ID等于本地号码。