#include < iostream >
#include < pthread.h >
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void* Func(void *)
{
pthread_mutex_lock(&mutex);
cout << "First thread execution" << endl;
pthread_mutex_unlock(&mutex);
}
int main()
{
pthread_t th1;
pthread_create(&th1, NULL, Func, NULL);
pthread_mutex_lock(&mutex);
cout << "In main thread" << endl;
pthread_mutex_lock(&mutex);
// pthread_join(th1, NULL); // Note this code is commented
return 0;
}
我已经在linux fedora 22(也在http://www.cpp.sh/上)执行了以下程序大约20次,在20次执行中我发现了以下输出: -
输出1:
In main thread
First thread execution
输出2:
First thread execution
In main thread
输出3:
In main thread
输出4:
In main thread
First thread execution
First thread execution
预计输出1到3,因为主线程没有等待子线程退出。两个线程(main和child)的执行顺序完全依赖于内核线程调度。
但输出4很奇怪!!! First thread execution
被打印两次!!!
现在,如果我在取消注释代码'pthread_join(th1,NULL)'或添加'pthread_exit(NULL)'后运行程序,我就不会得到奇怪的输出(即First thread execution
从未打印过两次),甚至我运行代码10000次。
我向专家提出的问题是:
First thread execution
打印了两次?pthread_join的责任是获取特定线程的退出代码,并且在成功调用pthread_join之后,内核将释放该特定线程的资源。如果我不在可连接线程上调用pthread_join那么它会导致资源泄漏,但为什么上面提到了奇怪的行为?
我们可能会说,这是未定义的行为,但如果有任何专家就此提供技术解释,那将会很棒。
感谢提前专家..
答案 0 :(得分:1)
我在类似情况下观察过这种双面打印。当您的线程在$check = mysql_query("SELECT user_task_types, user_task_types_id FROM dotp_user_task_type WHERE user_id = '$user_id'");
$row = mysql_fetch_array($check);
$user_task_types = explode(',',$row[0]);
$user_task_types_id = explode(',', $row[1]);
$new_array = array();
foreach($user_task_types as $key => $val)
{
$new_array[$user_task_types_id[$key]] = $val;
}
系统调用中等待正常输出时,特别是在此堆栈中:
write
程序正常终止,正常终止导致输出子系统刷新所有缓冲区。 stdin上的输出缓冲区尚未标记为空闲(写入系统调用尚未返回),因此它被再次写出:
#0 0x00007ffff78f4640 in write () from /lib64/libc.so.6
#1 0x00007ffff788fb93 in _IO_file_write () from /lib64/libc.so.6
#2 0x00007ffff788fa72 in new_do_write () from /lib64/libc.so.6
#3 0x00007ffff7890e05 in _IO_do_write () from /lib64/libc.so.6
#4 0x00007ffff789114f in _IO_file_overflow () from /lib64/libc.so.6
在任何情况下,加入你的线程(如果你使用C ++线程,它会提醒你这样做)或以其他方式同步对输出流的访问。
答案 1 :(得分:0)
主线程可能早于生成的线程结束。
结束主线程意味着结束整个过程,同时所有线程突然停止。这可能会调用未定义的行为,因此任何事情都可能发生。
绕过这个
pthread_join()
,{/ li>中的main()
加入衍生线程
pthread_exit()
结束主线程,它只是结束主线程并使进程不会结束。