Concurrency/Multithreading: 是否可以通过这种方式生成相同的输出?
Concurrency/Multithreading: Is it possible to generate the same output this way?
一个线程应该向上计数,另一个向下计数。输出各不相同,但它通常能够很好地打印 countUp() 部分,然后在 countDown() 部分中出现一些缺陷。最初,我确定问题出在两个线程都在争夺 cout 资源。我认为这可以通过 shared_print() 和互斥体来解决。但是,输出仍然会有所不同,坦率地说,我并没有全神贯注于这个 concurrency/multithreading 东西。我的主要问题是,是否有可能生成相同的输出,或者它总是会以某种方式变化吗?提前致谢。
mutex mu;
int counter= 0;
int main()
{
thread t1(countUp); //t1 starts running
thread t2(countDown); //t2 starts running
t1.join();
t2.join();
}
//Counts up from 0 to 20
void countUp()
{
while(counter < 20)
{
counter++;
shared_print(string("Counting Up: "), counter);
//counter++;
}
}
//Counts down from 20 to 0
void countDown()
{
while(counter > 0)
{
//counter--;
shared_print(string("Counting Down: "), counter);
counter--;
}
}
//Prints both of the counts
void shared_print(string description, int number)
{
lock_guard<std::mutex> guard(mu);
//mu.lock();
cout << description << number << endl;
//mu.unlock();
}
输出与此不同:
Counting Up: 1
Counting Up: 2
Counting Up: 3
Counting Up: 4
.
.
.
Counting Up: 20
对此(注意在倒计时开始时用 1 代替 20):
Counting Up: 1
Counting Up: 2
Counting Up: 3
Counting Up: 4
Counting Up: 5
Counting Up: 6
Counting Up: 7
Counting Up: 8
Counting Up: 9
Counting Up: 10
Counting Up: 11
Counting Up: 12
Counting Up: 13
Counting Up: 14
Counting Up: 15
Counting Up: 16
Counting Up: 17
Counting Up: 18
Counting Up: 19
Counting Up: 20
Counting Down: 1
Counting Down: 19
Counting Down: 18
Counting Down: 17
Counting Down: 16
Counting Down: 15
Counting Down: 14
Counting Down: 13
Counting Down: 12
Counting Down: 11
Counting Down: 10
Counting Down: 9
Counting Down: 8
Counting Down: 7
Counting Down: 6
Counting Down: 5
Counting Down: 4
Counting Down: 3
Counting Down: 2
Counting Down: 1
使用条件变量等待,等待操作自动释放互斥量。
mutex mu;
atomic<int> counter = 0;
condition_variable m_cvO;
//Counts up from 0 to 20
void countUp()
{
unique_lock<mutex> lck(mu);
m_cvO.wait(lck, [&]() {
return counter < 20;
});
while (counter < 20)
{
counter++;
shared_print(string("Counting Up: "), counter);
//counter++;
}
m_cvO.notify_all();
}
//Counts down from 20 to 0
void countDown()
{
unique_lock<mutex> lck(mu);
m_cvO.wait(lck, [&]() {
return counter > 0;
});
while (counter > 0)
{
//counter--;
shared_print(string("Counting Down: "), counter);
counter--;
}
m_cvO.notify_all();
}
//Prints both of the counts
void shared_print(string description, int number)
{
//mu.lock();
cout << description << number << endl;
//mu.unlock();
}
一个线程应该向上计数,另一个向下计数。输出各不相同,但它通常能够很好地打印 countUp() 部分,然后在 countDown() 部分中出现一些缺陷。最初,我确定问题出在两个线程都在争夺 cout 资源。我认为这可以通过 shared_print() 和互斥体来解决。但是,输出仍然会有所不同,坦率地说,我并没有全神贯注于这个 concurrency/multithreading 东西。我的主要问题是,是否有可能生成相同的输出,或者它总是会以某种方式变化吗?提前致谢。
mutex mu;
int counter= 0;
int main()
{
thread t1(countUp); //t1 starts running
thread t2(countDown); //t2 starts running
t1.join();
t2.join();
}
//Counts up from 0 to 20
void countUp()
{
while(counter < 20)
{
counter++;
shared_print(string("Counting Up: "), counter);
//counter++;
}
}
//Counts down from 20 to 0
void countDown()
{
while(counter > 0)
{
//counter--;
shared_print(string("Counting Down: "), counter);
counter--;
}
}
//Prints both of the counts
void shared_print(string description, int number)
{
lock_guard<std::mutex> guard(mu);
//mu.lock();
cout << description << number << endl;
//mu.unlock();
}
输出与此不同:
Counting Up: 1
Counting Up: 2
Counting Up: 3
Counting Up: 4
.
.
.
Counting Up: 20
对此(注意在倒计时开始时用 1 代替 20):
Counting Up: 1
Counting Up: 2
Counting Up: 3
Counting Up: 4
Counting Up: 5
Counting Up: 6
Counting Up: 7
Counting Up: 8
Counting Up: 9
Counting Up: 10
Counting Up: 11
Counting Up: 12
Counting Up: 13
Counting Up: 14
Counting Up: 15
Counting Up: 16
Counting Up: 17
Counting Up: 18
Counting Up: 19
Counting Up: 20
Counting Down: 1
Counting Down: 19
Counting Down: 18
Counting Down: 17
Counting Down: 16
Counting Down: 15
Counting Down: 14
Counting Down: 13
Counting Down: 12
Counting Down: 11
Counting Down: 10
Counting Down: 9
Counting Down: 8
Counting Down: 7
Counting Down: 6
Counting Down: 5
Counting Down: 4
Counting Down: 3
Counting Down: 2
Counting Down: 1
使用条件变量等待,等待操作自动释放互斥量。
mutex mu;
atomic<int> counter = 0;
condition_variable m_cvO;
//Counts up from 0 to 20
void countUp()
{
unique_lock<mutex> lck(mu);
m_cvO.wait(lck, [&]() {
return counter < 20;
});
while (counter < 20)
{
counter++;
shared_print(string("Counting Up: "), counter);
//counter++;
}
m_cvO.notify_all();
}
//Counts down from 20 to 0
void countDown()
{
unique_lock<mutex> lck(mu);
m_cvO.wait(lck, [&]() {
return counter > 0;
});
while (counter > 0)
{
//counter--;
shared_print(string("Counting Down: "), counter);
counter--;
}
m_cvO.notify_all();
}
//Prints both of the counts
void shared_print(string description, int number)
{
//mu.lock();
cout << description << number << endl;
//mu.unlock();
}