线程正常终止
int pthread_join(pthread_t thread, void **retval);
int pthread_detach(pthread_t thread);
void pthread_exit(void *retval);
线程正常终止的方法:
1、return从线程函数返回。
2、通过调用函数pthread_exit使线程退出
3. 线程可以被同一进程中的其他线程取消。
主线程、子线程调用exit, pthread_exit,互相产生的影响。
1、在主线程中,在main函数中return了或是调用了exit函数,则主线程退出,且整个进程也会终止,
此时进程中的所有线程也将终止。因此要避免main函数过早结束。
2、在主线程中调用pthread_exit, 则仅仅是主线程结束,进程不会结束,进程内的其他线程也不会结束,
知道所有线程结束,进程才会终止。
3、在任何一个线程中调用exit函数都会导致进程结束。进程一旦结束,那么进程中的所有线程都将结束。
为什么要使用pthread_join?
线程终止最重要的问题是资源释放的问题。
线程终止时需要注意线程同步的问题。一般情况下,进程中各个线程的运行是相互独立的,线程的终止不会相互通知,也不会影响其他线程,
终止的线程所占用的资源不会随着线程的结束而归还系统,而是仍为线程所在的进程持有。在Linux中,默认情况下是在一个线程被创建后,必须使用此函数对创建的线程进行资源回收,但是可以设置Threads attributes来设置当一个线程结束时,直接回收此线程所占用的系统资源,详细资料查看Threads attributes。
函数pthread_join用来等待一个线程的结束,pthread_join的调用者将被挂起并等待thread线程终止。需要注意的是一个线程仅允许一个线程使用pthread_join
等待它结束,并且被等待的线程应该处于可join状态。即非DETACHED状态。DETACHED是指某个线程执行pthread_detach后所处的状态。处于DETACHED状态
的线程无法由pthread_join同步。
一个可pthread_join的线程所占用的资源仅当有线程对其执行了pthread_join后才会释放,因此为了防止内存泄漏,所有线程终止时,要么已经被设置为DETACHED状态
要么使用pthread_join来回收资源。
notice:
一个线程不能被多个线程等待。否则第一个收到信号的线程成功返回。其余调用pthread_join的线程返回错误码
ESRCH No thread with the ID thread could be found.
示例代码:
/* * pthreadExit.c * * Created on: 2020年9月11日 * Author: zzz */ #include <stdio.h> #include <pthread.h> #include <unistd.h> #include <stdlib.h> void* thread_func(void* arg) { printf("thread:%lu is running\n", pthread_self()); int rv = 44; pthread_exit((void*)rv); } int main() { pthread_t thid; int rv; pthread_create(&thid, NULL, thread_func, NULL); printf("main thread begin join\n"); pthread_join(thid, (void*)&rv); printf("main thread end join\n"); printf("the thread:%lu exit:%d\n", thid, rv); return 0; }
将线程的属性称为detached,则线程退出时会自己清理资源。
/* * threadDetachedT.c * * Created on: 2020年9月11日 * Author: zzz */ #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> void*start_run(void*arg) { printf("thread do something!\n"); } int main() { pthread_t thread_id; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(&thread_id, &attr, start_run, NULL); pthread_attr_destroy( &attr ); sleep(5); exit(0); }