今天阳光明媚,我与64位有个约会。
约会内容 如下:
首先,main中创建producer和consumer两个线程,然后等待两个线程执行完毕。
理论上讲,屏幕上依次会输出
Point 1
Point 2
Point 3
Unfortunately,代码在打印出Point 2后Segment Fault Core掉了,我将两个pthraed_join()交换位置,变成下面的样子:
fprintf(stderr,"Point 2/n");
pthread_join(consumer, (void *)&result);
fprintf(stderr, "Point 1/n");
pthread_join(producer, (void *)&result);
这次居然没有core。。。莫非,pthread_join和pthread_create还有顺序对应关系?不应该呀!man pthread_join看了下,没有相关注意事项,那么,有点囧了……
考虑到我是在实验室,莫非……莫非……于是在代码前面加了这么一句:
printf("int size: %d, void* size:%d/n", sizeof(int), sizeof(void*));
shit!输出为:
int size: 4
void* size: 8
囧,问题找到~ 原来这是个64位机器,int 和pointer的大小不一样了。
堆栈Layout如下:
main args Hi
pthread_t producer
pthread_t consumer
intresult Lo
第一个pthread_join会向result所在的堆栈处写数据(这里为全0),数据长度为8字节,于是乎,consumer的内容被破坏了,后面的pthread_join使用的consumer指针也就变成非法了。core之~~
如何避免这个问题呢? 最自然的方法就是改变result的定义:
long result;
long和void*都是占8字节。
还有个搞着玩的方法 ,仅仅这段代码中适用,那就是改变consumer和producer的定义顺序:
pthread_t consumer;
pthread_t producer;
为什么呢?调用pthread_join()等待producer,返回后producer的内容会被result覆盖掉,恰好producer再也不会被使用了,坏了也就坏了。但是consumer还健在,下一个pthread_join照常执行。经过验证,OK~
这个道理跟上面交换两个pthread_join的顺序是相通的。
----
我养的太阳花还没见发芽,然而那一盆土上已经长出了五颜六色的草儿,每天清晨趴在床头看一看,也是十分的赏心悦目呢~~