2つのスレッドで2つのものを無限ループで計算したいのですが、それらの2つはお互いに依存していません。同じスレッドをループで作って、同じミューテックスを何度も何度も繰り返さないようにしてください。
また、私は無限ループでも端末に出力したい(最後の出力が計算されるたびに再起動し、間に何かのステップは必要ない)。したがって、私はすべて安全な状態にあるグローバル変数(最初の計算の2回の連続した反復と2番目の計算の1つの値)のローカルコピーをいくつか求めます。
問題は、func1から何らかの出力を得るために2つの計算にいくつかの睡眠を追加する必要があることです。私はCPU使用量を確認し、睡眠は間違いなくそれを下げます。 どうすればこの問題を回避できますか?
また、テストのためのコメントを参照してください:
#include <iostream>
#include <thread>
#include <condition_variable>
#include <mutex>
int n(0);
long s(1234);
double t(56.78);
std::condition_variable cond;
std::mutex m1;
std::mutex m2;
void func1() {
while (true) {
// Not needed due to wait unlocking the mutex
//std::this_thread::sleep_for(std::chrono::nanoseconds(1));
std::unique_lock<std::mutex> lck1(m1);
cond.wait(lck1);
int n1(n);
long s1(s);
cond.wait(lck1);
int n2(n);
long s2(s);
lck1.unlock();
std::unique_lock<std::mutex> lck2(m2);
double ti(t);
lck2.unlock();
// calculate and print some output
std::this_thread::sleep_for(std::chrono::milliseconds((n1*n2)/2));
std::cout << n1 << ":" << s1 << ", " << n2 << ":" << s2 << ", " << ti << std::endl;
}
}
void func2() {
while (true) {
// Why do I need this to make func1 ever proceed (ok, really seldom and random func1 got the mutex) and
// how to work around this without sleep lowering time for computations?
std::this_thread::sleep_for(std::chrono::nanoseconds(1)); // comment out to test
std::unique_lock<std::mutex> lck1(m1);
n++;
// do some stuff taking some time with s
std::this_thread::sleep_for(std::chrono::milliseconds((n*n)/3));
cond.notify_all();
}
}
void func3() {
while (true) {
// Why do I need this to make func1 ever proceed (it got the mutex never ever) and
// how to work around this without sleep lowering time for computations?
std::this_thread::sleep_for(std::chrono::nanoseconds(1)); // comment out to test
std::unique_lock<std::mutex> lck2(m2);
// do something taking some time with t
std::this_thread::sleep_for(std::chrono::seconds(2));
}
}
int main() {
std::thread t1(func1);
std::thread t2(func2);
std::thread t3(func3);
t1.join();
t2.join();
t3.join();
return 0;
}
t3でt1とt2をトリガーし、次にt1とt2でt3をトリガーするように見えます。 4つのミューテックスを使うことができます.t1にはm1、t2にはm2、t3にはm31、m32があります。 t1はm1を待って作業を行い、m31を解放します。 t1はm2を待って作業を行い、m32を解放します。 t3はm31からm32を待ち、作業を行い、m1とm2を解放します。 – rcgldr
あなたの問題を再現する実際のビルド可能な実行可能コードを投稿してください。 [mcve]の投稿について読む。 –
@rcgldrこのアイデアは素晴らしいですが、2つの連続した値が得られるとは限りません。あるいは、私はちょうどそれが間違っている。 –