假設您希望並行運行一個節,然後合併回主線程,然後再並行回到節,依此類推。類似於童年遊戲的紅燈綠燈。C++分叉連接並行阻塞
我已經給出了一個我想要做的例子,我使用一個條件變量在開始時阻止線程,但希望並行地啓動它們,但是最後阻止它們他們可以連續打印出來。 * =操作可能是一個跨越數秒的更大的操作。重用線程也很重要。使用任務隊列可能太重了。
我需要使用某種形式的阻塞結構,它不僅僅是一個簡單的忙碌循環,因爲我知道如何用繁忙循環來解決這個問題。
在英國:
- 線索1產生10個線程被阻塞
- 線程1個信號的所有線程開始(而不阻斷海誓山盟)
- 螺紋2-11處理其專用存儲器
- 線程1正在等待2-11完成(可以在這裏使用原子計數)
- 線程2-11完成,每個線程都可以通知1以檢查其條件(如有必要)
- 線程1個檢查其狀態並打印陣列
- 線程1個resignals 2-11再次處理,由2-
實施例的代碼(幼稚適於從例如在cplusplus.com)繼續:
// condition_variable example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
#include <atomic>
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
std::atomic<int> count(0);
bool end = false;
int a[10];
void doublea (int id) {
while(!end) {
std::unique_lock<std::mutex> lck(mtx);
while (!ready) cv.wait(lck);
a[id] *= 2;
count.fetch_add(1);
}
}
void go() {
std::unique_lock<std::mutex> lck(mtx);
ready = true;
cv.notify_all();
ready = false; // Naive
while (count.load() < 10) sleep(1);
for(int i = 0; i < 10; i++) {
std::cout << a[i] << std::endl;
}
ready = true;
cv.notify_all();
ready = false;
while (count.load() < 10) sleep(1);
for(int i = 0; i < 10; i++) {
std::cout << a[i] << std::endl;
}
end = true;
cv.notify_all();
}
int main() {
std::thread threads[10];
// spawn 10 threads:
for (int i=0; i<10; ++i) {
a[i] = 0;
threads[i] = std::thread(doublea,i);
}
std::cout << "10 threads ready to race...\n";
go(); // go!
return 0;
}
爲什麼'count'原子?爲什麼在一邊使用條件變量並在另一邊使用繁忙的睡眠? – UmNyobe
@UmNyobe我明確不想使用繁忙的睡眠。線程應該在等待被通知的時候睡覺。 對於你的另一個問題,count是原子的,因爲它可以通過多個線程同時增加一些運氣。增量是一個兩階段過程。 –