【问题标题】:C++ Printing/cout overlaps in multithreading?C ++打印/ cout在多线程中重叠?
【发布时间】:2014-09-15 12:54:41
【问题描述】:

我想知道在使用多线程时如何处理打印。
我认为这很简单:

#include <iostream>
#include <pthread.h>
using namespace std;

bool printing = false;

struct argumentStruct {
    int a;
    float b;
};

void *ThreadFunction(void *arguments) {
  struct argumentStruct*args = (struct argumentStruct*)arguments;
  int a = args->a;
  float b = args->b;
    while (printing) {}
    printing = true;
      cout << "Some text...." << a << b << endl;
    printing = false;
}

main() {
    pthread_t threads[3];
    struct argumentStruct argStruct[3];

    argStruct[0].a = 1;
    argStruct[0].b = 1.1;
    pthread_create(&threads[0], NULL, &ThreadFunction, (void *)&argStruct[0]);

    argStruct[1].a = 2;
    argStruct[1].b = 2.2;
    pthread_create(&threads[1], NULL, &ThreadFunction, (void *)&argStruct[1]);

    argStruct[2]a = 3;
    argStruct[2].b = 3.3;
    pthread_create(&threads[2], NULL, &ThreadFunction, (void *)&argStruct[2]);

    getchar();
    return 0;
}

但这并没有那么好。一些 couts 只是被跳过(或者可能被覆盖?)。
那么我做错了什么?我该如何正确处理?

【问题讨论】:

  • 有个东西叫mutex ...
  • printing 将缺乏所有线程的统一可见性。建议您使用适当的并发机制(互斥锁、锁...)。
  • 您可以尝试volatile bool printing 或使用std::mutex。如果没有您的实际代码,很难知道还有什么建议。
  • 另一件需要注意的事情:即使使用std::mutex,您所做的只是确保不会同时发生多个写入。来自不同线程的输出仍然可以以任何顺序发生。

标签: c++ multithreading printing cout


【解决方案1】:

问题在于测试和设置printing 变量的语句不是原子,即它们不会在不被操作系统调度程序中断的情况下执行,而操作系统调度程序会在线程之间切换 CPU。您应该使用mutexes 以便在打印时停止其他线程。这里有一个很好的例子:

http://sourcecookbook.com/en/recipes/70/basic-and-easy-pthread-mutex-lock-example-c-thread-synchronization

【讨论】:

  • 谢谢,您链接中的示例效果很好。 :)
【解决方案2】:

您有一个竞争条件,其中两个(或更多)线程都可以将printing 设置为true

这是因为赋值不是原子操作,它是由CPU分多步完成的,如果线程在实际设置变量为true之前就被中断了,另外一个线程开始运行,那么您可以让两个线程同时运行,都相信变量是true。为了更清楚:

  1. 线程 A 发现 printingfalse
  2. 线程 A 被中断
  3. 线程 B 开始运行
  4. 线程 B 发现 printingfalse
  5. 线程 B 将 printing 设置为 true
  6. 线程 B 被中断
  7. 线程 A 已调度并再次开始运行
  8. 线程 A 将 printing 设置为 true

现在线程 A 和 B 都在全速运行。

这就是为什么会有处理这些事情的线程原语,例如 semaphoresmutex

【讨论】:

  • 您的回答分析了问题,但没有提供解决方案(我没有将“有信号量和互斥体”算作解决方案)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-29
相关资源
最近更新 更多