【问题标题】:C++ Multithreading avoiding interleaving during function callsC ++多线程避免函数调用期间的交错
【发布时间】: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 写入标准输出,它里面有一个互斥锁吗?

标签: c++ multithreading


【解决方案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 在这种情况下你的任务无法解决,你不能同时有两件事情并同时进行
猜你喜欢
  • 2020-02-25
  • 1970-01-01
  • 1970-01-01
  • 2014-04-03
  • 2012-03-30
  • 1970-01-01
  • 1970-01-01
  • 2019-08-12
  • 1970-01-01
相关资源
最近更新 更多