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 中的线程调用期间控制函数的打印语句

C语言如何终止线程

如何在 Cython 中调用多线程 C 函数?

C语言如何终止线程?

Python 3.X 调用多线程C模块,并在C模块中回调python函数的示例

java里面,c里面都有回调函数,回调函数都是啥东西啊???