【问题标题】:Bizarre thread printing behaviour奇怪的线程打印行为
【发布时间】:2010-01-28 18:28:34
【问题描述】:

嘿 - 我编写的一个小玩具程序遇到了一个奇怪的问题,用于尝试线程。
这是我的代码:

#include <pthread.h>
#include <iostream>

using std::cout;
using std::endl;

void *threadFunc(void *arg) {
    cout << "I am a thread. Hear me roar." << endl;

    pthread_exit(NULL);
}

int main() {
    cout << "Hello there." << endl;
    int returnValue;
    pthread_t myThread;

    returnValue = pthread_create(&myThread, NULL, threadFunc, NULL);

    if (returnValue != 0) {
        cout << "Couldn't create thread! Whoops." << endl;
        return -1;
    }

    return 0;
}

由于 main 中的第一个 cout 没有被注释掉,线程打印正常。
但是,没有它,线程根本不会打印任何内容。

有什么帮助吗?

【问题讨论】:

  • 请记住,默认情况下 C++ 流不是线程安全的。同时在多个线程中写入 cout 可能会导致问题。通常在周六凌晨 3:00 之前未被检测到,此时客户端调用并说服务器崩溃了......

标签: c++ multithreading pthreads


【解决方案1】:

试试这个:

#include <pthread.h>
#include <iostream>

using std::cout;
using std::endl;

void *threadFunc(void *arg) {
    cout << "I am a thread. Hear me roar." << endl;

    pthread_exit(NULL);
}

int main() {
    //cout << "Hello there." << endl;
    int returnValue;
    pthread_t myThread;

    returnValue = pthread_create(&myThread, NULL, threadFunc, NULL);

    if (returnValue != 0) {
        cout << "Couldn't create thread! Whoops." << endl;
        return -1;
    }

    pthread_join( myThread, NULL);

    return 0;
}

我的代码和你的代码之间的区别是一行 - pthread join。这会暂停主线程,直到子线程有机会完成其操作。

在您的代码中,执行到达第一个 cout 并被处理。然后,您拆分另一个线程,主线程一直持续到结束,在整理辅助线程之前可能会或可能不会到达。这就是奇怪的行为出现的地方 - 你所遇到的是主程序在子线程有机会之前完成的情况,所以程序已经“返回”并且整个过程都被内核清理了。

【讨论】:

    【解决方案2】:

    这是一个竞争条件,允许程序在主循环需要一段时间才能运行时工作。您的程序甚至在线程有机会运行之前就退出了。

    在从 main() 返回之前,您应该等待线程完成(请参阅pthread_join)。

    【讨论】:

      【解决方案3】:

      它在一种情况下有效的事实是纯粹的运气。你有一个时间问题,即你的程序在你的线程工作之前就退出了。

      main() 退出时,你的所有线程都会死掉。在main() 退出之前,您需要进行某种等待以使其他线程有时间运行。创建工作线程后,尝试在main() 中添加cin,看看会发生什么。

      最终你会想要某种运行循环和消息/事件在线程之间进行通信。

      -杰夫

      【讨论】:

        【解决方案4】:

        尝试在 main 的末尾,return 0 之前添加一个pthread_exit(NULL);。我怀疑问题出在您的main 返回并且进程在线程有机会打印之前退出。从main 打印可能会以某种方式修改时间,以便线程确实 有机会打印——但这只是运气。您需要确保在所有线程完成工作之前 main 不会返回。从 main 调用 pthread_exit 允许其他线程继续运行,直到它们也调用了 pthread_exit

        【讨论】:

          猜你喜欢
          • 2014-06-10
          • 2018-03-06
          • 1970-01-01
          • 1970-01-01
          • 2015-01-27
          • 1970-01-01
          • 1970-01-01
          • 2012-03-31
          相关资源
          最近更新 更多