如何使线程顺序而不是并发运行?

时间:2013-08-12 12:52:47

标签: c++ multithreading c++11

例如,我希望每个线程在前一个线程完成之前不开始运行,是否有标志,如thread.isRunning()

#include <iostream>
#include <vector>
#include <thread>
using namespace std;

void hello() {
    cout << "thread id: " << this_thread::get_id() << endl;
}

int main() {

    vector<thread> threads;

    for (int i = 0; i < 5; ++i)
        threads.push_back(thread(hello));


    for (thread& thr : threads)
        thr.join();

    cin.get();
    return 0;
}

我知道线程是要同时运行的,但如果我想要控制订单呢?

7 个答案:

答案 0 :(得分:3)

没有thread.isRunning()。你需要一些同步原语来做到这一点。 例如,考虑std::condition_variable

答案 1 :(得分:3)

一种平易近人的方式是使用std::async。使用std::async的当前定义是由std :: async启动的操作的关联状态可能导致返回的std::future的析构函数阻塞,直到操作完成。这可能会限制可组合性并导致代码看起来并行运行,但实际上是顺序运行。

{
    std::async(std::launch::async, []{ hello(); });
    std::async(std::launch::async, []{ hello(); });  // does not run until hello() completes
}

答案 2 :(得分:2)

您不能简单地控制顺序,例如说“首先,线程1,然后是线程2,......”您将需要使用同步(即std::mutex和条件变量{{1} })。
您可以创建事件以阻止一个线程,直到某个事件发生。

有关C ++中的线程机制的概述,请参阅cppreference

答案 3 :(得分:1)

如果我们需要第二个线程在第一个线程完成后开始运行,真的需要一个线程吗?

对于解决方案,我认为尝试设置一个全局标志,在第一个线程中设置值,并在启动第二个线程时,首先检查标志应该有效。

答案 4 :(得分:0)

您需要使用信号量或锁定。
如果将信号量初始化为值0:
在thread.start()之后调用wait并在线程执行函数结束时调用signal / release(例如在java中运行函数,OnExit函数等...)

因此主线程将一直等待,直到线程循环完成其执行。

答案 5 :(得分:0)

基于任务的并行性可以实现这一点,但C ++目前不提供任务模型作为其线程库的一部分。如果您有TBB或PPL,您可以使用他们基于任务的设施。

答案 6 :(得分:0)

我认为您可以通过使用C ++ 11中的std::mutexstd::condition_variable来实现。为了能够按顺序运行所使用的布尔数组,当线程完成某些工作时,它将在该数组的特定索引中写入true。 例如:

mutex mtx;
condition_variable cv;
int ids[10] = { false };

void shared_method(int id) {
    unique_lock<mutex> lock(mtx);

    if (id != 0) {
        while (!ids[id - 1]) {
            cv.wait(lock);
        }
    }

    int delay = rand() % 4;
    cout << "Thread " << id << " will finish in " << delay << " seconds." << endl;
    this_thread::sleep_for(chrono::seconds(delay));

    ids[id] = true;
    cv.notify_all();
}

void test_condition_variable() {    
    thread threads[10];

    for (int i = 0; i < 10; ++i) {
        threads[i] = thread(shared_method, i);
    }

    for (thread &t : threads) {
        t.join();
    }
}

输出:

Thread 0 will finish in 3 seconds.
Thread 1 will finish in 1 seconds.
Thread 2 will finish in 1 seconds.
Thread 3 will finish in 2 seconds.
Thread 4 will finish in 2 seconds.
Thread 5 will finish in 0 seconds.
Thread 6 will finish in 0 seconds.
Thread 7 will finish in 2 seconds.
Thread 8 will finish in 3 seconds.
Thread 9 will finish in 1 seconds.