我的代码生成的输出是不明确的。
int main()
{
cout << "THIS IS AN THREADING EXAMPLE IN C++" << endl;
cout<<"MAIN , reverse and forward are executed"<<endl;
thread rev_thread(print_reverse,1);
thread for_thread(print_forwward,1);
rev_thread.join();
for_thread.join();
cout << "AIN , reverse and forward are DONE" << endl;
return 0;
}
void print_reverse(int wait_sec)
{
for(int rev=5000;rev>=1;rev--)
{
//std::this_thread::sleep_for (std::chrono::seconds(wait_sec));
cout<<"The rev ::" << rev<<endl;
}
}
void print_forwward(int wait_sec)
{
for(int forw=1;forw<=5000;forw++)
{
//std::this_thread::sleep_for (std::chrono::seconds(wait_sec));
cout<<"The forward ::" << forw<<endl;
}
}
我期望以任意随机方式混合使用print_forwward和print_reverse **
但这就是我得到的:-
转速:: 4997
转速:: 4996
转速:: 4995
转速:: 4994
转速:: 4993
转速:: 4992
转速:: 4991
转速:: 4990
转速:: 4989
转速:: 4988
转速:: 4987
转速:: 4986
前锋:: 2
前进:: 3
前进:: 4
前进:: 5
前进:: 6
前进:: 7
前进:: 8
转速:: 4985
转速:: 4984
转速:: 4983
转速:: 4982
转速:: 4981
前进::放牧:: 4980
转速:: 4979
9转速:: 4978
转速:: 4977
转速:: 4976
前锋:: 10
前进:: 11
前进:: 12
前进:: 13
前进:: 14
转速::前进:: 15
前进:: 16
4975前进:: 17
前进:: 18
前进:: 19
前进:: 20
前进:: 21
前进:: 22
转速::前锋:: 234974
前进:: 24
前锋:: 25
234974到底是什么?而且打印版本可以单行前进?
请注意,间隙也以与输出相同的方式打印!
我在这里注释了等待测试的内容
请注意,我是这个概念的新手。
任何帮助将不胜感激
答案 0 :(得分:2)
用于流的C ++运算符<<
并非“线程安全”;意思是说,没有什么能阻止控件在std::cout << x << y;
的输出和x
的输出之间的类似y
的表达式中间的线程之间进行切换。
您看到的是23
紧随其后的4974
。
不幸的是,由于操作员定义了令人讨厌的接口,使其变得“线程安全”也不是一件容易的事(不是不可能,但是很烦人)。
实际上,字符串格式方法la printf
对此也更好。
答案 1 :(得分:1)
234974到底是什么?以及打印版本和前进 一条线??!!请注意,间隙也以相同的方式打印 作为输出!在这里,我已注释掉等待测试的内容,请注意 我是这个概念的新手。任何帮助将不胜感激
对我来说很明显,您的输出“混合” 是发生了,只是比您预期的更有趣或与众不同。我发现这种“中断” /“交错”输出(在串行设备上)甚至在实时操作系统中也是如此。
我期望print_forwward和print_reverse任意混合 方式**
合理。但是您尚未确定正在运行的操作系统,也未确定有多少个活动的内核都可以促进或改变您的结果。
我认为可以通过使用互斥量来容忍(cout缺乏线程安全性)问题,这样一次只能有1个线程可以退出。
最简单的重构可能是在每个cout之后(在for循环中)在前面的互斥锁()和解锁()。
您可以考虑将cout-of-a值替换为大向量中的push-of-a值。是的,向量也需要互斥访问,但是由于基于内存,推送应该比cout快得多。 (对不起,我还没测量。)
在我的实验中,10个(默认)线程(在2核心硬件上)将值推入向量(初始值为5000万的初始值),持续10秒。完成填充向量的“竞赛”后,一个线程将向量内容引出到文件中以供以后分析(最新测试内容约为3,700万个字符。简要报告说,该代码花费了大约3秒钟的时间来编写向量内容转换为文本文件。)
writing ID sequence of 31,862,791 values to ./Q6.txt
complete: 2,968,610 us
(任意)10秒持续时间是通过线程主线程在10个线程运行时几乎不执行任何操作来测量的。以下代码段用于线程的启动和连接之间,并且还会产生一个“进度cout”(因为其他线程不使用cout)
// threads start
// progress indicator to user
for (size_t i = 0; i < MaxSecs; ++i) // let threads switch for 10 seconds
{
sleepToWallClockStartOfSec(); // 'main()' sync's to wall clock
cout << (MaxSecs-i-1) << ' ' << flush; // "9 8 7 6 5 4 3 2 1 0"
}
m_done = true; // command threads to exit - all threads can see m_done
// threads joins
Linux使我感到惊讶……完成了很少的上下文切换。