C ++多线程避免函数调用期间的交错
Posted
技术标签:
【中文标题】C ++多线程避免函数调用期间的交错【英文标题】:C++ Multithreading avoiding interleaving during function calls 【发布时间】:2018-03-30 19:30:07 【问题描述】:int main()
thread t1([] printer("*", 100); );
thread t2([] printer("+", 100); );
t1.join();
t2.join();
void printer(string c, int num)
for (int i = 1; i <= num; i++)
cout << c;
cout << endl;
现在这会打印出类似 ****+++** 我希望它在一行中打印 *** 然后在一行中打印 +++ 所有内容。我们不允许使用互斥锁或阻止线程访问打印机功能。代码仍然必须是多线程的。
关于如何做到这一点的任何想法?
【问题讨论】:
简单 - 在第一个线程完成之前不要启动第二个线程。 从措辞上看,这听起来像是一个家庭作业,所以必须满足这里的限制条件。但一般来说,如果您需要完成一项任务然后再执行另一项任务,这不适合多线程,毕竟这是关于同时执行的。 @bananas -- 回应您的评论,是的,这与多线程不一致,那是因为 要求 与多线程不一致。 (我之前的评论是在你最近的评论之前写的) 听上去像是老师想到了一些特殊技巧的课堂作业。这就像通常的垃圾“不使用 a,b,c 做 x”,其中 a,b,c 是正确、正常的做事方式 "不允许使用互斥锁或阻塞线程" - 你知道 cout 写入标准输出,它里面有一个互斥锁吗? 【参考方案1】:给每个printer
自己的缓冲区,并从main
打印结果:
void printer(ostream& oss, string c, int num)
for (int i = 1; i <= num; i++)
oss << c;
int main()
stringstream s1, s2;
thread t1([&] printer(s1, "*", 10); );
thread t2([&] printer(s2, "+", 10); );
t1.join();
t2.join();
cout << s1.str() << s2.str() << endl;
return 0;
main
为每个线程准备单独的输出缓冲区,让每个线程同时填充其缓冲区,并等待线程完成。一旦两个线程都返回,main
将结果打印到cout
。
【讨论】:
@drescherjm 实际上从 c++11 开始可以同时使用cout
@Slava 你的意思是回复 tobi303 对 cwschmidt 的回答的评论吗?【参考方案2】:
积累数据,然后一次性输出:
void printer(string c, int num)
std::string buff;
for (int i = 1; i <= num; i++)
buff += c;
cout << buff << endl;
【讨论】:
对,我也不喜欢它们。我不认为你的回答有什么问题,而且我认为任何在其用户照片上带有可爱 Лосяш 的人都值得点赞:-)【参考方案3】:先写入字符串流而不是直接输出将解决同步问题:
#include <iostream>
#include <string>
#include <sstream>
#include <thread>
void printer(std::string c, int num)
std::stringstream strm;
for (int i = 1; i <= num; i++)
strm << c;
std::cout << strm.str() << std::endl;
int main()
std::thread t1([] printer("*", 100); );
std::thread t2([] printer("+", 100); );
t1.join();
t2.join();
【讨论】:
如果你有多个“ 哼..你也许是对的,虽然我不相信;)。必须做一些研究 删除您的评论,使我的回复毫无意义,请下次研究,然后再否决... 我撤回了我的反对票,我认为删除我的评论没有问题,您的回复也没有任何意义。它让我重新考虑我的陈述,所以它实现了它的目的...... 是的,当然。但是新读者不知道,为什么我的回复在那里,没有你的初步评论;-)【参考方案4】:在启动t2
之前让主线程等待t1
:
thread t1([] printer("*", 100); );
t1.join();
thread t2([] printer("+", 100); );
t2.join();
【讨论】:
是的,我已经尝试过了,但被告知这不是一个有效的解决方案,因为您现在基本上一次只运行一个线程,而不是同时运行多个线程。 不使用任何额外的线程将是一种更高效、更优雅的解决方案。 @bananas 在这种情况下你的任务无法解决,你不能同时有两件事情并同时进行以上是关于C ++多线程避免函数调用期间的交错的主要内容,如果未能解决你的问题,请参考以下文章
多线程 - 如何在 python 中的线程调用期间控制函数的打印语句