当前位置:   article > 正文

07LinuxC线程学习之pthread_exit函数和总结exit、return、pthread_exit,pthread_cancel各自退出效果和join,detach的作用

pthread_exit

1 pthread_exit函数

void pthread_exit(void *retval);	
/*
	功能:退出当前子线程。与在某个函数中返回区别一下。
	参1:retval表示线程退出状态,通常传NULL。
*/
  • 1
  • 2
  • 3
  • 4
  • 5

2 exit的作用

1)测试1
下面的程序和结果可以看到,当执行到第二个线程时,我们调用了exit(0),导致后面3,4,5线程没有打印。也就是说,该函数会将整个进程退出,无论在哪个线程中。

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

int func(int a){
    exit(0);
}

void *tfn(void *arg){
    int i;

    i = (int)arg;
    sleep(i);
    if (i == 2){
    	func(8888);//测试1
    	//return NULL;//测试2
    	//func(8888);//测试3
    }

    printf("I'm %dth thread, Thread_ID = %lu\n", i+1, pthread_self());

    pthread_exit(NULL);
}

int main(int argc, char *argv[]){
    int n = 5, i;
    pthread_t tid[n];
	for (i = 0; i < n; i++) {
        tid[i] = -1;
    }
    
    for (i = 0; i < n; i++) {
        pthread_create(&tid[i], NULL, tfn, (void *)i);
    }
	
	//为了方便观察,不回收
	//for (i = 0; i < n; i++) {
        //pthread_join(tid, NULL);
    //}    

    printf("I am main, and I am not a process, I'm a thread!\n" 
            "main_thread_ID = %lu\n", pthread_self());

    return 0;
}
  • 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

程序结果:
在这里插入图片描述

3 return的作用

1)测试2
同样的代码,我们将func函数中的exit改成return NULL,可以看到结果1能够依次打印。
结果1:
在这里插入图片描述
2)测试3
然后再将return NULL封装一下放在一个新的函数func中返回,重新调用func,可以看到结果2,我们想要退出线程3,但却没有退出。

void* func(){
	return NULL;
}
  • 1
  • 2
  • 3

结果2:
在这里插入图片描述

  • 所以可以总结到return的作用是:返回到调用者处。有可能会退出进程(放在主线程时),有可能会退出线程,也有可能什么也不退出。

3 pthread_exit的作用

将测试3的代码改成下面,可以看到结果,线程3退出了。所以pthread_exit的作用是只退出当前子线程,记住是只。即使你放在主线程,它也会只退出主线程,其它线程有运行的仍会继续运行。

void* func(){
	pthread_exit(NULL);
}
  • 1
  • 2
  • 3

结果:
在这里插入图片描述

所以我们可以大总结这些退出函数的作用了。

4 总结exit、return、pthread_exit,pthread_cancel各自退出效果和pthread_join,pthread_detach的作用

  • 1)return:返回到调用者那里去。注意,在主线程退出时效果与exit,_exit一样。即return有可能会退出进程(放在主线程时),有可能会退出线程,也有可能什么也不退出。
  • 2)pthread_exit():只退出当前子线程。注意:在主线程退出时,其它线程不会结束。同样可以执行。所以这个只字非常重要。并且,与return一样,pthread_exit退出的线程也需要调用pthread_join去回收子线程的资源(8k左右),否则服务器长时间运行会浪费资源导致无法再创建新线程。
  • 3)exit,_exit: 将进程退出,无论哪个子线程调用整个程序都将结束。
  • 4)pthread_join():阻塞等待回收子线程。
  • 5)pthread_cancel():可以杀死子线程,但必须需要一个契机,这个契机就是系统调用。一般方法是调用pthread_testcancel提供契机处理。并且join再回收该被杀死的子线程的返回值为pthread.h中的宏#define PTHREAD_CANCELED ((void *) -1)。
  • 6)pthread_detach:1)注意,所有线程的错误号返回都只能使用strerror这个函数判断,不能使用perror,因为perror是调用进程的全局错误号,不适合单独线程的错误分析,所以只能使用strerror。2)线程可以被置为detach状态,这样的线程一旦终止就立刻回收它占用的所有资源,而不保留终止状态。不能对一个已经处于detach状态的线程调用pthread_join,这样的调用将返回EINVAL错误。也就是说,如果已经对一个线程调用了pthread_detach就不能再调用pthread_join了。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/181953
推荐阅读
相关标签
  

闽ICP备14008679号