1. 多线程退出的方式如下:

  • 线程调用pthread.exit()
  • 线程调用return
  • 线程所属进程结束
  • 线程被其它线程通知结束或者结束

  前两种方式也称为线程的主动结束,是理想状况,但是需要注意一点,线程结束(非分离状态),资源却没有释放,需要调用pthread_join()

  后两种称为被动结束,其中第三种是很异常的情况,而第四种有时是我们希望这么做的, 比如某个线程非常耗时,我们希望线程结束

2. 主动结束

  return 只是结束其所属的函数,而pthread_exit则是结束其所属的线程,若在线程函数中,则二者没有区别

  

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

static int gs_num;

void *pth_fun(void *arg)
{
    printf("I am a pthread\n");
    gs_num = 100;
    pthread_exit((void*)&gs_num);
}

int main(void)
{
    pthread_t pth;
    int ret = pthread_create(&pth, NULL, pth_fun, NULL);
    if (ret) {
        printf("create pthread error\n");
        return 0;
    }
    int *data = 0;
    pthread_join(pth, (void*)&data);
    printf("data = %d\n", *data);
    sleep(2);
    printf("hello world!\n");
    return 0;
 } 

执行结果如下:

kunmzhao@build-245:~$ gcc 1.c -pthread
kunmzhao@build-245:~$ ./a.out
I am a pthread
data = 100
hello world!

改成pthread_join改成return,效果一样

 

3. 被动结束

  其它线程发送信号取消线程

  3.1 pthread_kill

    int pthread_kill(pthread_t threadId, int signal)

    1) threadId:线程号

    2) signal:信号

    返回值:成功:0,失败:errno

    注意:1. 该函数不仅仅用来结束线程,通过signal可传递多个信号     

       2. 接收该信号的线程需要事先注册该信号的处理函数,类似Qt的信号槽   

          3. on_signal_fun中的pthread_exit换成return, 则不能结束线程

       4. 该函数可以判断某个线程是都存活,发送信号为0,若pthread_kill 的返回值为 ESRCH ,则线程已经退出或者不存在

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <signal.h>


void on_signal_fun(int sig)
{
    printf("sig = %d\n", sig);
    printf("received a quit signal\n");
    pthread_exit(NULL);  // exit pthread 
}

void *pth_fun(void *arg)
{
    signal(SIGQUIT, on_signal_fun); // register the exit function
    printf("I am a pthread\n");    
    while (1)
    {
        continue;
    }
    return NULL;
}

int main(void)
{
    pthread_t pth;
    int ret = pthread_create(&pth, NULL, pth_fun, NULL);
    if (ret) {
        printf("create pthread error\n");
        return 0;
    }
    sleep(5);
    pthread_kill(pth, SIGQUIT);
    pthread_join(pth, NULL);
    printf("hello world!\n");
    return 0;
 } 

运行结果如下:

kunmzhao@build-245:~$ gcc 1.c -pthread
kunmzhao@build-245:~$ ./a.out
I am a pthread
sig = 3
received a quit signal
hello world!
kunmzhao@build-245:~$

 

  3.2 pthread_cancel 

  int pthread_cancel(pthread_t thread) 

  thread:线程号

  返回值:成功:0, 失败:errno

  注意点:1. 该函数发送成功,线程也不会立即结束,只有在线程调用库函数时候才会结束

      2. 针对第一点可以用 void pthread_testcancel(void) 进行判断,尤其在死循环中尤为好用 

      

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <signal.h>


void *pth_fun(void *arg)
{
    printf("I am a pthread\n");    
    int i = 0;
    while (1)
    {
        i++;
        pthread_testcancel();
    }
    return NULL;
}

int main(void)
{
    pthread_t pth;
    int ret = pthread_create(&pth, NULL, pth_fun, NULL);
    if (ret) {
        printf("create pthread error\n");
        return 0;
    }
    sleep(5);
    pthread_cancel(pth);
    pthread_join(pth, NULL);
    printf("hello world!\n");
    return 0;
 } 

运行结果如下:

kunmzhao@build-245:~$ gcc 1.c -lpthread
kunmzhao@build-245:~$ ./a.out
I am a pthread
hello world!

如果将上述代码中的pthrea_testcancel()去掉, 虽然pthread_cancel信号发送成功, 但是线程却不会退出   

 

posted on 2021-04-19 16:43  阿明明  阅读(550)  评论(0)    收藏  举报