【线程】注意的几个问题。

  • pthread_kill可以判断一个线程是否退出--Demo程序
  • 在使用pthread_cancel去结束线程时,被结束线程函数不能有返回值,即在发送cancel指令时,线程必须是live的状态。否则会产生“段错误”
  • pthread_cancel并不能立即退出线程(实测必须进行延时即可退出线程),发送cancel指令成功后,必须使用pthread_join去等待退出线程
  • 使用pthread_join时,线程属性必须是线程合并
  • 使用pthread_join退出线程后,不能在使用phtread_kill去判断线程是否退出,因为pthread_join退出线程后,被等待线程的资源被收回。线程的tid会被回收,所以用pthread_kill(tid)会发生"segmentation fault".
  • 设置线程分离属性后,线程结束后会自动进行资源回收。
  • 在没有设置线程属性时,默认线程合并
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include<stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
 
void *func1()/*1秒钟之后退出*/
{
  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);           //allow to exit thread  
  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,   NULL);   //set thread canncel immediately
   printf("pthread1(ID:0x%x)。\n",(unsigned int)pthread_self());
    while(1)
    {
         
    }
     
    //pthread_exit((void *)0);
}
  
void *func2()/*5秒钟之后退出*/
{
     pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);           //allow to exit thread  
  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,   NULL);   //set thread canncel immediately
  printf("pthread2(ID:0x%x)。\n",(unsigned int)pthread_self());
    while(1);
   // printf("pthread2(ID:0x%x)exit。\n",(unsigned int)pthread_self());
  //  pthread_exit((void *)0);
  return NULL;
}
  
void test_pthread(pthread_t tid) /*pthread_kill的返回值:成功(0) 线程不存在(ESRCH) 信号不合法(EINVAL)*/
{
    int pthread_kill_err;
    pthread_kill_err = pthread_kill(tid,0);
  
    if(pthread_kill_err == ESRCH)
        printf("ID 0x%x is not exist。\n",(unsigned int)tid);
    else if(pthread_kill_err == EINVAL)
        printf("signal 。\n");
    else
        printf("ID 0x%x live pthread_kill_err=%d。\n",(unsigned int)tid,pthread_kill_err);
}
  
int main()
{
    int ret;
    pthread_t tid1,tid2;
    pthread_attr_t   attr;
  pthread_attr_init(&attr);  
 
    pthread_create(&tid1,&attr,func1,NULL);
    pthread_create(&tid2,&attr,func2,NULL);
      
    sleep(3);/*创建两个进程3秒钟之后,分别测试一下它们是否还活着*/
if(!pthread_cancel(tid1))  
    
 
      pthread_join(tid1, NULL);
      printf("pthread 1 cancel OK\n");  
 
    }
 
    if(!pthread_cancel(tid2))  
    
      pthread_join(tid2, NULL); 
      printf("pthread 2 cancel OK\n");  
    }
   // sleep(1);//发送cancel指令后,延时可以结束线程。如果不使用延时,则使用pthread_join来阻塞结束(pthread_join的方法)
    test_pthread(tid1);/*测试ID为tid1的线程是否存在*/
    test_pthread(tid2);/*测试ID为tid2的线程是否存在*/
  
    exit(0);
}

  

posted @   轻轻的吻  阅读(159)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示