回顾下多线程基础,随手写了个bug。
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
const int MAXNUM = 10;
void *func(void *arg)
{
int *pInt = (int *)arg;
printf("pthread_id = %ld, arg = %d\n",pthread_self(),*pInt);
}
int main(int argc,char *argv[])
{
pthread_t pthreads[MAXNUM];
for(int i = 1;i <= MAXNUM;i++)
{
pthread_create(&pthreads[i],NULL,func,(void *)&i);
}
sleep(2);
for(int i = 1;i <= MAXNUM;i++)
{
pthread_join(pthreads[i],NULL);
}
}
编译:gcc -lpthread main.c -o main
出错:
对‘pthread_create’未定义的引用
对‘pthread_join’未定义的引用
collect2: error: ld returned 1 exit status
把链接库换个位置 gcc main.c -o main -lpthread,这样就行了,Ubuntu真操蛋。
运行下试试:
嗯?
为啥?
出错了?
找谁背锅?
问题出在了传参上,so加个打印参数地址瞅瞅。
printf("arg address = %p\n",arg);
搞一把:
地址都一样,为啥呢?
其实问题出在了传参方式上,对所有线程来说它们公用 i的地址。在线程创建的时候并非先创建的就一定先执行,后创建的进程可能会把 i的值修改掉,所以导致在运行函数中去取 i的值是不准确的。
改进
方案一:(void *)&i ===> (void *)i;
搞一把:
gdb登场
问题一目了然,
非法访问内存,这个解决方案有点拍脑袋了。
方案二:
int *tmp = (int *)malloc(sizeof(int));
*tmp = i;
(void *)&i ===> (void*)tmp;
搞一把:
嗯,这回正常了,不过要记得有个malloc没有释放。
总结
就算是拍脑袋也要搞一把











网友评论