免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2158 | 回复: 6
打印 上一主题 下一主题

[Linux] pthread進程全域資源造成pthread_exit()操作無效? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-08-19 10:53 |只看该作者 |倒序浏览
各位先進好

今天我寫了一隻socket的程式,
從主線程創建一個socket初始化的副線程thread_sockClientInit
該副線程也為分離型態的thread

裡面做一些與socket server連線握手等功能

當確認握手完後又在thread_sockClientInit()裏頭做了一個分離的thread_sockKeepAlive線程
然後就自己透過pthread_exit()回收掉自己

但在top跟ps裏頭,會發現thread_sockClientInit並無如期的回收掉
猜想是否因為裡頭掛了一些全域的socket變數,所以才造成pthread_exit()以及先前嘗試的pthread_cancel(pthread_self());
都無法正常的把該thread給移除呢?




以下是程式碼片段:

  1. int client_sockfd;
  2. int len;
  3. struct sockaddr_in remote_addr; // SERVER STRUCT
  4. char buff[BUFFER_SIZE];  // SOCK BUFFER
  5. void clean(void* p)
  6. {
  7.         printf("clean()\n");
  8. }
  9. int thread_sockClientInit()
  10. {
  11.         memset(&remote_addr,0,sizeof(remote_addr)); // 數據初始化
  12.         remote_addr.sin_family=AF_INET; // 設置為IP通訊
  13.         remote_addr.sin_addr.s_addr=inet_addr(ServerIP);//ServerIP
  14.         remote_addr.sin_port=htons(ServerPort); // ServerPort
  15.         // 建立連接端socket--IPv4,TCP
  16.         if((client_sockfd=socket(PF_INET,SOCK_STREAM,0))<0)
  17.         {
  18.                 perror("client socket creation failed");
  19.                 exit(EXIT_FAILURE);
  20.         }
  21.         // SOCKET資訊開啟
  22.         if(connect(client_sockfd,(struct sockaddr *)&remote_addr,sizeof(struct sockaddr))<0)
  23.         {
  24.                 perror("[Cloud]->>CServer connect failed");
  25.         }
  26.         else{
  27.                 char initalCmd[]="xxxxxxxxxinit string~~~";

  28.                 send(client_sockfd,initalCmd,strlen(initalCmd),0);
  29.                 // 接收SERVER訊息
  30.                 len=recv(client_sockfd,buff,BUFFER_SIZE,0);
  31.                 printf("[Cloud]->>>Receive from server:%s\n",buff);
  32.                 if(len<0)
  33.                 {
  34.                         perror("[Cloud]->>>Receive from server failed.<<<");
  35.                         exit(EXIT_FAILURE);
  36.                 }
  37.                 else{
  38.                         printf("[Cloud]->>>Sock init complete.<<<\n");

  39.                         sockNTP();
  40.                         sleep(1);
  41.                         printf("[Cloud]->>>Start sockKeepAlive Process.<<<\n");

  42.                         //KEEPALIVE為detached型態。
  43.                         pthread_attr_t attr;
  44.                         pthread_attr_init (&attr);
  45.                         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

  46.                         pthread_t pid_sockKeepAlive;
  47.                         int pret = pthread_create(&pid_sockKeepAlive,&attr, (void *) thread_sockKeepAlive, NULL);
  48.                         if(pret!=0)
  49.                         {
  50.                                 printf ("Create pthread thread_sockInit error!\n");
  51.                                 exit (1);
  52.                         }
  53.                         pthread_attr_destroy (&attr);
  54.                 }
  55.         }
  56.         //close(client_sockfd);// 關閉SOCKET
  57.         printf ("2EXIT pthread thread_sockInit!\n");
  58.         pthread_exit(NULL);
  59. }

  60. int main(){
  61.         pthread_attr_t tattr;
  62.         pthread_attr_init (&tattr);
  63.         pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
  64.         pthread_t pid_sockInit;
  65.         pret = pthread_create(&pid_sockInit,&tattr, (void *) thread_sockClientInit, NULL);
  66.         if(pret!=0)
  67.         {
  68.                 printf ("[Main]->>>Create pthread thread_sockClientInit error!<<<\n");
  69.                 exit (1);
  70.         }
  71.         pthread_attr_destroy (&tattr);
  72.         sleep(10);
  73.         return(0);
  74. }

复制代码

论坛徽章:
17
处女座
日期:2013-08-27 09:59:352015亚冠之柏太阳神
日期:2015-07-30 10:16:402015亚冠之萨济拖拉机
日期:2015-07-29 18:58:182015年亚洲杯之巴勒斯坦
日期:2015-03-06 17:38:17摩羯座
日期:2014-12-11 21:31:34戌狗
日期:2014-07-20 20:57:32子鼠
日期:2014-05-15 16:25:21亥猪
日期:2014-02-11 17:32:05丑牛
日期:2014-01-20 15:45:51丑牛
日期:2013-10-22 11:12:56双子座
日期:2013-10-18 16:28:17白羊座
日期:2013-10-18 10:50:45
2 [报告]
发表于 2013-08-19 15:40 |只看该作者
回复 1# thkaw


    确认已经执行pthread_exit()了?你在main函数中写法有很大问题,如果main函数返回将导致进程退出,这将使得进程内所有线程被终止。无论创建的线程是否detach都不应无视既存线程的状态通过简单的sleep后退出。如果你使用pthread_cancel的话需要使用pthread_cleanup_push注册资源清理函数,否则资源不能正常释放。

论坛徽章:
0
3 [报告]
发表于 2013-08-19 16:19 |只看该作者
本帖最后由 djsxut 于 2013-08-19 16:20 编辑

可能是thread_sockClientInit这个函数执行的太快, 在pthread_create函数返回之前就停止了运行,停止运行后就很有可能将线程号和系统资源移交给thread_sockKeepAlive线程使用。试试在 int pret = pthread_create(&pid_sockKeepAlive,&attr, (void *) thread_sockKeepAlive, NULL); 后多睡眠下。

论坛徽章:
0
4 [报告]
发表于 2013-08-19 17:51 |只看该作者
本帖最后由 thkaw 于 2013-08-19 17:52 编辑

謝謝兩位先進

我發現是小弟我愚鈍...搞了個烏龍!

其實進程還是有被回收掉
只是因為thread_sockClientInit裏頭創建thread_sockKeepAlive的速度太快
加上創建完該thread後緊接著把自己結束掉,
所以在top底下看起來thread數量並沒有增減的情況!

我剛剛在int pret = pthread_create(&pid_sockKeepAlive,&attr, (void *) thread_sockKeepAlive, NULL);
後面sleep(2)秒

在觀察了top之後
才恍然大悟...

所以我的clean也是正常的,exit也是沒問題的


完全是自己大意疏忽掉了

论坛徽章:
0
5 [报告]
发表于 2013-08-20 11:24 |只看该作者
用繁体字, 是台湾或者香港的吗? {:3_189:}

论坛徽章:
0
6 [报告]
发表于 2013-08-22 10:03 |只看该作者
回复 5# djsxut


   
哈哈,我是台灣的

剛學習Linux編程還不到兩個月~
未來涵請多多指教!

论坛徽章:
0
7 [报告]
发表于 2013-08-22 11:23 |只看该作者
呵呵, 互相学习。{:3_189:} 回复 6# thkaw


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP