深夜本来都打算弄完睡觉,结果被一个莫名其妙的锁搞得莫名其妙,为了让同步问题明显地表现出来,主线程和子线程都加了一个sleep 1秒,使得都来不及减减操作,if判断就都为真,导致结果变成了-1,但这不是想要的结果
于是想通过互斥量加锁,让一个if以及减减线执行完,然后解锁再执行另一个,可居然还是返回-1,更奇怪的是,去掉两个线程里的sleep,锁就起效果了,难道是这中间的具体实现流程问题没完全弄清楚?
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
int i = 1;
pthread_mutex_t mutex;
void *thread_function(){
pthread_mutex_lock(&mutex);
if (i > 0){
sleep(1);
--i;
}
pthread_mutex_unlock(&mutex);
pthread_exit("See you, lihui");
}
int main(){
pthread_t child;
if (pthread_create(&child, NULL, thread_function, NULL)){
printf("Create new thread failed!\n");
exit(1);
}
pthread_mutex_lock(&mutex);
if (i > 0){
sleep(1);
--i;
}
pthread_mutex_unlock(&mutex);
pthread_join(child, NULL);
printf("i = %d\n", i);
return 0;
}
执行,神奇的结果:
lihui@2015 ~ $ ./a.exe i = -1
这就很奇怪了,这锁应该加得没问题呀,只好gdb了一把,但是神奇的一幕出现了:
Reading symbols from ./a.exe...done. (gdb) b 12 Breakpoint 1 at 0x1004010f1: file he.c, line 12. (gdb) b 27 Breakpoint 2 at 0x100401184: file he.c, line 27. (gdb) r Starting program: /home/lihui/a.exe [New Thread 6772.0x1b9c] [New Thread 6772.0xf3c] [New Thread 6772.0x1da4] Breakpoint 2, main () at he.c:27 27 sleep(1); (gdb) c Continuing. [Switching to Thread 6772.0x1da4] Breakpoint 1, thread_function () at he.c:12 12 sleep(1); (gdb) c Continuing. [Thread 6772.0x1da4 exited with code 0] i = -1
主线程和子线程的if判断居然都为真,也就是这锁完全没起作用?这就奇怪了,这么简单的程序,感觉没明显错误呀,抱着试一试的态度,把两个sleep给去掉,不试不知道,一试吓一跳:
lihui@2015 ~ $ ./a.exe i = 0
但其实这样做是没道理的,因为没有了sleep,不加锁执行结果也会是0,就因为这样我猜加了两个sleep凸显一下问题,但事实上加了sleep的确结果就变了,已经开始怀疑在锁里加sleep会不会有不明确的问题,还搜索了半天,一无所获
准备收工睡觉的时候,不死心,心想会不会是cygwin的问题,直接copy sourcecode到服务器linux系统执行了一把,神了,加sleep结果也是0,顿时心中突然冒出来多少只那啥,上次一个程序也是,还好这次没浪费太多时间
[lihui@localhost ~]# gcc -g hello.c -lpthread [lihui@localhost ~]# ./a.out i = 0 ... Reading symbols from /root/a.out...done. (gdb) b 12 Breakpoint 1 at 0x4007ac: file hello.c, line 12. (gdb) b 27 Breakpoint 2 at 0x400828: file hello.c, line 27. (gdb) r Starting program: /root/a.out [Thread debugging using libthread_db enabled] [New Thread 0x7ffff7ff2700 (LWP 9063)] Breakpoint 2, main () at hello.c:27 27 sleep(1); Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.107.el6.x86_64 (gdb) c Continuing. i = 0 [Thread 0x7ffff7ff2700 (LWP 9063) exited] Program exited normally. Missing separate debuginfos, use: debuginfo-install libgcc-4.4.7-4.el6.x86_64 (gdb)
果然,只跳进去了一个sleep,锁生效了,难道cygwin和linux有关thread加锁也有这么大差异??
