- 论坛徽章:
- 0
|
题记:弄清楚线程何时启动,怎么结束!
转载时请注明出处和作者联系方式
文章出处:
http://www.limodev.cn/blog
作者联系方式:李先静
前几天帮同事查一个多线程的BUG,不到十秒钟我就找到了问题的根源。N年前我曾犯过类似的错误,呵,今天仍然有人在重复。这些问题都比较典型,把它们写出来,供新手参考吧。
o 用临时变量作为线程参数的问题。
#include
#include
#include
void* start_routine(void* param)
{
char* str = (char*)param;
printf("%s:%s\n", __func__, str);
return NULL;
}
pthread_t create_test_thread()
{
pthread_t id = 0;
char str[] = "it is ok!";
pthread_create(&id, NULL, start_routine, str);
return id;
}
int main(int argc, char* argv[])
{
void* ret = NULL;
pthread_t id = create_test_thread();
pthread_join(id, &ret);
return 0;
}
分析:由于新线程和当前线程是并发的,谁先谁后是无法预测的。可 能create_test_thread 已经执行完成,str已经被释放了,新线程才拿到这参数,此时它的内容已经无法确定了,自然打印出的字符串是随机的。
o 线程参数共享的问题。
#include
#include
#include
void* start_routine(void* param)
{
int index = *(int*)param;
printf("%s:%d\n", __func__, index);
return NULL;
}
#define THREADS_NR 10
void create_test_threads()
{
int i = 0;
void* ret = NULL;
pthread_t ids[THREADS_NR] = {0};
for(i = 0; i
分析:由于新线程和当前线程是并发的,谁先谁后是无法预测的。i在不断变化,所以新线程拿到的参数值是无法预知的,自然打印出的字符串也是随机的。
o 虚假并发。
#include
#include
#include
void* start_routine(void* param)
{
int index = *(int*)param;
printf("%s:%d\n", __func__, index);
return NULL;
}
#define THREADS_NR 10
void create_test_threads()
{
int i = 0;
void* ret = NULL;
pthread_t ids[THREADS_NR] = {0};
for(i = 0; i
分析:因为pthread_join会阻塞直到线程退出,所以这些线程实际上是串行执行的,一个退出了,才创建下一个。当年一个同事写了一个多线程的测试程序,就是这样写的,结果没有测试出一个潜伏的问题,直到产品运行时,这个问题才暴露出来
在某个机器的运行结果:
ʹÓÃÄÚ½¨ specs¡£
Ä¿±ê£ºi386-redhat-linux
ÅäÖÃΪ£º../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=i386-redhat-linux
Ïß³ÌÄ£ÐÍ£ºposix
gcc °æ±¾ 4.1.0 20060304 (Red Hat 4.1.0-3)
[root@dep4 test]#
(3)
[root@dep4 test]# ./tes
start_routine:0
start_routine:1
start_routine:2
start_routine:3
start_routine:4
start_routine:5
start_routine:6
start_routine:7
start_routine:8
start_routine:9
[root@dep4 test]#
(2)
[root@dep4 test]# ./pthreadtes
start_routine:0
start_routine:1
start_routine:2
start_routine:3
start_routine:4
start_routine:5
start_routine:6
start_routine:7
start_routine:8
start_routine:9
[root@dep4 test]# ./pthreadtes
start_routine:8
start_routine:8
start_routine:8
start_routine:8
start_routine:4
start_routine:5
start_routine:6
start_routine:7
start_routine:8
start_routine:9
[root@dep4 test]# ./pthreadtes
(1)
start_routine:
[root@dep4 test]# ./lpthreadtes
start_routine:
[root@dep4 test]# ./lpthreadtes
start_routine:
[root@dep4 test]# ./lpthreadtes
start_routine:
[root@dep4 test]# ./lpthreadtes
start_routine:
[root@dep4 test]# ./lpthreadtes
start_routine:
[root@dep4 test]#
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/64117/showart_2146391.html |
|