POSIX线程专有数据的空间释放问题,pthread_key_create……(
2011-09-09 02:03
399 查看
先记下来,以后有机会请教高手
最近学习通过pthread_key_create创建的线程专有数据时发现如果不对线程使用pthread_join,则不会调用pthread_key_create所指定的资源释放函数。而并没有像书上所说的在线程pthread_exit()后就会调用释放函数。这是为什么?究竟什么情况下会调用?
我使用的测试程序:
这是程序输出
----------------------------------------------
hello
thread 1083395264 enter
thread 1091783744 enter
thread 1091783744 returns 1091783744
thread 1083395264 returns 1083395264
destructor excuted in thread 1075005312, param=1091783744
main thread 1075005312 exit
----------------------------------------------
这是在网上看到的一篇文章,个人认为并不是pthread_join接受线程时才调用每个线程的key的echomsg函数。而是由于pthread_join阻塞等待特定的线程结束,以至于被等待的线程能够全部处理完(当然包括每个线程key的特定清理函数echomsg),所以当pthread_join尤其用在main线程中时,能够确保特定的子线程能处理完。
在以上程序中,稍加修改:child2()函数中的sleep睡眠时间都改为sleep(1),并且把主函数的pthread_join(tid2,NULL);也注释掉,重新编译执行也会得到上面类似的结果。
同时也发现child1的线程也退出了,并没有sleep(5)足够的时间,我认为是child2线程结束时要发送信号,而sleep是可被信号中断的(这个陈述稍有欠当,姑且是那个意思),所以child1的线程在child2结束后也结束了。但是没来及执行child1的echomsg,main线程就结束了,随之整个进程也结束了
个人认为上面的程序有点隐形的bug,自己改进的代码如下:
程序输出:
hello
pthread_key_t init in the once_run
thread1 -1208583280 enter
thread2 -1219073136 enter
thread2 -1219073136 returns -1219073136
thread1 -1208583280 returns -1208583280
destructor excuted in thread -1219073136, param=-1219073136
main thread -1208580400 exit
-到此结束-
最近学习通过pthread_key_create创建的线程专有数据时发现如果不对线程使用pthread_join,则不会调用pthread_key_create所指定的资源释放函数。而并没有像书上所说的在线程pthread_exit()后就会调用释放函数。这是为什么?究竟什么情况下会调用?
我使用的测试程序:
#include <pthread.h > #include <stdio.h > #include <unistd.h > using namespace std; pthread_key_t key; void echomsg(void* p) { int t=*(int*)p; printf( "destructor excuted in thread %d, param=%d\n ",pthread_self(),t); } void* child1(void* arg) { int*ptid= new int; *ptid=pthread_self(); printf( "thread %d enter\n ",*ptid); pthread_setspecific(key,(void*)ptid); sleep(2); printf( "thread %d returns %d\n ",*ptid,*((int*)pthread_getspecific(key))); sleep(5); pthread_exit(NULL); return NULL; } void* child2(void* arg) { int*ptid= new int; *ptid=pthread_self(); printf( "thread %d enter\n ",*ptid); pthread_setspecific(key,(void*)ptid); sleep(1); printf( "thread %d returns %d\n ",*ptid,*((int*)pthread_getspecific(key))); sleep(5); pthread_exit(NULL); return NULL; } int main() { pthread_t tid1,tid2; printf( "hello\n "); pthread_key_create(&key,echomsg); pthread_create(&tid1,NULL,child1,NULL); pthread_create(&tid2,NULL,child2,NULL); //pthread_join(tid1,NULL); pthread_join(tid2,NULL); sleep(3); pthread_key_delete(key); printf( "main thread %d exit\n ",pthread_self()); return 0; }
这是程序输出
----------------------------------------------
hello
thread 1083395264 enter
thread 1091783744 enter
thread 1091783744 returns 1091783744
thread 1083395264 returns 1083395264
destructor excuted in thread 1075005312, param=1091783744
main thread 1075005312 exit
----------------------------------------------
这是在网上看到的一篇文章,个人认为并不是pthread_join接受线程时才调用每个线程的key的echomsg函数。而是由于pthread_join阻塞等待特定的线程结束,以至于被等待的线程能够全部处理完(当然包括每个线程key的特定清理函数echomsg),所以当pthread_join尤其用在main线程中时,能够确保特定的子线程能处理完。
在以上程序中,稍加修改:child2()函数中的sleep睡眠时间都改为sleep(1),并且把主函数的pthread_join(tid2,NULL);也注释掉,重新编译执行也会得到上面类似的结果。
同时也发现child1的线程也退出了,并没有sleep(5)足够的时间,我认为是child2线程结束时要发送信号,而sleep是可被信号中断的(这个陈述稍有欠当,姑且是那个意思),所以child1的线程在child2结束后也结束了。但是没来及执行child1的echomsg,main线程就结束了,随之整个进程也结束了
个人认为上面的程序有点隐形的bug,自己改进的代码如下:
#include <pthread.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> //atexit using namespace std; pthread_key_t key; pthread_once_t thread_once = PTHREAD_ONCE_INIT; void echomsg(void *); void once_run(void) { printf("pthread_key_t init in the once_run\n "); pthread_key_create(&key,echomsg); } void echomsg(void* p) { int t=*(int*)p; printf( "destructor excuted in thread %d, param=%d\n ",pthread_self(),t); delete (int *)p; } void* child1(void* arg) { int*ptid= new int; pthread_once(&thread_once, once_run);//测试pthread_once是否还会在此执行不,因为在main线程已经执行了. *ptid=pthread_self(); printf( "thread1 %d enter\n ",*ptid); pthread_setspecific(key,(void*)ptid); sleep(2); printf( "thread1 %d returns %d\n ",*ptid,*((int*)pthread_getspecific(key))); sleep(5); pthread_exit(NULL); return NULL; } void* child2(void* arg) { int*ptid= new int; *ptid=pthread_self(); printf( "thread2 %d enter\n ",*ptid); pthread_setspecific(key,(void*)ptid); sleep(1); printf( "thread2 %d returns %d\n ",*ptid,*((int*)pthread_getspecific(key))); sleep(1); pthread_exit(NULL); return NULL; } void main_exit() { pthread_key_delete(key); } int main() { pthread_t tid1,tid2; printf( "hello\n "); atexit(main_exit);//为了防止sleep(4)放到pthread_key_delete(key)后面就会出现段错误了。但是个人也不很提倡用atexit这个函数。 pthread_once(&thread_once, once_run); //pthread_key_create(&key,echomsg); //保证一次性运行把其放到了pthread_once了 pthread_create(&tid1,NULL,child1,NULL); pthread_create(&tid2,NULL,child2,NULL); //pthread_join(tid1,NULL); //pthread_join(tid2,NULL); sleep(3); //pthread_key_delete(key); printf( "main thread %d exit\n ",pthread_self()); return 0; }
程序输出:
hello
pthread_key_t init in the once_run
thread1 -1208583280 enter
thread2 -1219073136 enter
thread2 -1219073136 returns -1219073136
thread1 -1208583280 returns -1208583280
destructor excuted in thread -1219073136, param=-1219073136
main thread -1208580400 exit
-到此结束-
相关文章推荐
- POSIX线程专有数据的空间释放问题,pthread_key_create
- POSIX线程专有数据的空间释放问题,pthread_key_create
- mysql删除数据后不释放空间问题
- Posix线程中undefined reference to 'pthread_create'问题解决
- pthread库中操作线程专有数据的函数:pthread_key_create,pthread_setspecific,pthread_gtespecific,pthread_key_delete
- pthread_key_create()--创建线程私有数据|pthread_key_delete()--注销线程私有数据
- linux线程之线程私有数据 pthread_key_create方法的学习
- 多线程私有数据pthread_key_create
- undefined reference to 'pthread_create'问题解决
- 关于备份由 Mapinfo EasyLoader 上传到数据库的空间数据的问题
- PLSQL数据导入导出问题解决(空表、大字段表、表空间错误等)
- pthread_key_t和pthread_key_create()详解
- Oracle中关于清除数据释放表空间等方面的sql
- undefined reference to 'pthread_create'问题的解决
- 使用空间索引获取几何数据的问题
- undefined reference to 'pthread_create'问题解决【转载】
- oracle truncateb表后 表空间释放问题的解决办法
- oracle 数据表空间问题
- Linux下undefined reference to ‘pthread_create’问题解决
- 关于free如何知道要释放多少内存空间长度的问题