【发布时间】:2012-11-13 02:13:04
【问题描述】:
这是我的第一个 pthread 程序,我不知道为什么 printf 语句会在子线程中打印两次:
int x = 1;
void *func(void *p)
{
x = x + 1;
printf("tid %ld: x is %d\n", pthread_self(), x);
return NULL;
}
int main(void)
{
pthread_t tid;
pthread_create(&tid, NULL, func, NULL);
printf("main thread: %ld\n", pthread_self());
func(NULL);
}
在我的平台上观察到的输出(Linux 3.2.0-32-generic #51-Ubuntu SMP x86_64 GNU/Linux):
1.
main thread: 140144423188224
tid 140144423188224: x is 2
2.
main thread: 140144423188224
tid 140144423188224: x is 3
3.
main thread: 139716926285568
tid 139716926285568: x is 2
tid 139716918028032: x is 3
tid 139716918028032: x is 3
4.
main thread: 139923881056000
tid 139923881056000: x is 3
tid 139923872798464tid 139923872798464: x is 2
对于3,来自子线程的两条输出线
对于4,和3一样,连输出都是交错的。
【问题讨论】:
-
在多线程应用程序中,您需要担心多线程使用的资源,在您的示例中,屏幕输出是多线程使用的资源,因此需要使用互斥锁来处理。
-
@tAmirNaghizadeh:在 POSIX(和 Linux)上,使用
FILE*的函数被指定为锁定对象(少数 I/O 函数专门不锁定并将“解锁”作为他们名字的一部分)。 -
我知道我在上个月左右看到了另一个关于 SO 的问题,关于当线程未加入并且进程结束时额外的输出行,但我现在找不到它(也许它已被删除?)。一个从来没有得到满意回答的老的:stackoverflow.com/questions/10322175我希望能就此给出一个体面的答案。
-
@tAmirNaghizadeh:我认为当进程结束而不加入线程时,有时会导致线程输出重复的问题相同。我认为这是 glibc 中的一个问题,但我愿意有人指出为什么系统可以这样做(即指出未定义的行为在哪里)。我认为
printf()相对于进程中的其他printf()调用(实际上,任何使用stdout的POSIX 函数)应该是原子的论点在这个答案和cmets 中:stackoverflow.com/a/13190750/12711 -
对此的更新:这个问题有一个针对 glibc 的开放错误报告:sourceware.org/bugzilla/show_bug.cgi?id=14697