一、连接已终止的线程
功能:和一个已经终止的线程进行连接
回收子线程的资源
这个函数是阻塞函数,调用一次只能回收一个子线程
参数:thread:需要回收的子线程的ID
retval: 接收子线程推出时的返回值
返回值:0 成功
非0 失败,返回错误号
代码示例:
#include <stdio.h> #include <pthread.h> #include <string.h> #include <unistd.h> void *callback(void *arg) { printf("child pthread id:%ld\n", (long)pthread_self()); sleep(3); return NULL; } int main() { pthread_t tid; int ret = pthread_create(&tid, NULL, callback, NULL); if (ret != 0) { char *errstr = strerror(ret); printf("error: %s\n", errstr); return 1; } // 主线程 for (int i = 0; i < 5; i++) { printf("%d\n", i); } printf("tid:%ld, main thread id:%ld\n", (long)tid, (long)pthread_self()); //主线程调用pthread_join回收子线程的资源 ret=pthread_join(tid, NULL); if (ret != 0) { char *errstr = strerror(ret); printf("error: %s\n", errstr); return 1; } printf("回收子线程资源成功!\n"); // 等待子线程结束 pthread_exit(NULL); return 0; }
这里将在child id打印之后,睡眠3s才会打印回收子线程资源成功
#include <stdio.h> #include <pthread.h> #include <string.h> #include <unistd.h> //int value=10;//全局变量 void *callback(void *arg) { printf("child pthread id:%ld\n", (long)pthread_self()); // sleep(3); // return NULL; int value = 10;//局部变量 pthread_exit((void *)&value); } int main() { pthread_t tid; int ret = pthread_create(&tid, NULL, callback, NULL); if (ret != 0) { char *errstr = strerror(ret); printf("error: %s\n", errstr); return 1; } // 主线程 for (int i = 0; i < 5; i++) { printf("%d\n", i); } printf("tid:%ld, main thread id:%ld\n", (long)tid, (long)pthread_self()); // 主线程调用pthread_join回收子线程的资源 int *pthread_retval; ret = pthread_join(tid, (void **)&pthread_retval); if (ret != 0) { char *errstr = strerror(ret); printf("error: %s\n", errstr); return 1; } printf("xeti data:%d\n", *pthread_retval); printf("回收子线程资源成功!\n"); // 等待子线程结束 pthread_exit(NULL); return 0; }
二、线程分离
pthread_detach
是 POSIX 线程库中的一个函数,用于将线程标记为“分离状态”,以表明当线程退出时,其资源可以被系统自动回收,而不需要等待其他线程调用pthread_join
来获取线程的退出状态。以下是
pthread_detach
的基本语法:#include <pthread.h> int pthread_detach(pthread_t thread);
thread
:要标记为分离状态的线程的线程标识符。调用
pthread_detach
函数后,指定的线程就会变成“分离状态”的线程。这意味着当该线程退出时,它的资源(包括线程控制块等)会被自动回收,而不会形成僵尸线程。分离状态的线程不再需要其他线程调用pthread_join
来进行清理。代码示例:
#include <stdio.h> #include <pthread.h> #include <string.h> void *callback(void *arg) { printf("child pthread id:%ld\n", (long)pthread_self()); return NULL; } int main() { pthread_t tid; int ret = pthread_create(&tid, NULL, callback, NULL); if (ret != 0) { char *errstr = strerror(ret); printf("error1: %s\n", errstr); return 1; } printf("tid:%ld, main thread id:%ld\n", tid, pthread_self()); // 设置子线程分离,子线程分离后,子线程结束时对应的资源就不需要主线程释放 ret = pthread_detach(tid); if (ret != 0) { char *errstr = strerror(ret); printf("error2: %s\n", errstr); return 1; } ret = pthread_join(tid, NULL); if (ret != 0) { char *errstr = strerror(ret); printf("error3: %s\n", errstr); return 1; } // 等待子线程结束 pthread_exit(NULL); return 0; }
此时已经子线程分离了,在调用pthread_join就会报错
三、线程取消
pthread_cancel
是 POSIX 线程库中的一个函数,用于请求取消另一个线程的执行。这个函数的使用需要非常小心,因为线程可能正在执行一些关键的任务,而取消可能引起资源泄漏或不一致性的问题。以下是
pthread_cancel
的基本语法:#include <pthread.h> int pthread_cancel(pthread_t thread);
thread
:要取消的线程的线程标识符。调用
pthread_cancel
函数将发送一个取消请求给指定的线程。实际上,它并不会立即终止线程的执行,而是等待线程到达取消点(cancellation point)。取消点是一些由线程库定义的特定位置,线程在这些位置上检查是否有取消请求。如果线程在取消点上,它会执行相应的取消动作。如果线程没有到达取消点,取消请求会在线程到达下一个取消点时生效。要使一个线程支持取消请求,可以使用以下两个函数:
pthread_setcancelstate:
#include <pthread.h> int pthread_setcancelstate(int state, int *oldstate);
state
:用于设置取消状态的值,可以是PTHREAD_CANCEL_ENABLE
(启用取消)或PTHREAD_CANCEL_DISABLE
(禁用取消)。oldstate
:用于存储原始取消状态的变量的地址。如果不关心原始状态,可以将其设置为NULL
。pthread_setcanceltype:
#include <pthread.h> int pthread_setcanceltype(int type, int *oldtype);
type
:用于设置取消类型的值,可以是PTHREAD_CANCEL_DEFERRED
(延迟取消)或PTHREAD_CANCEL_ASYNCHRONOUS
(异步取消)。oldtype
:用于存储原始取消类型的变量的地址。如果不关心原始类型,可以将其设置为NULL
。代码示例:
#include <pthread.h> #include <stdio.h> #include <unistd.h> void *thread_function(void *arg) { pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); while (1) { printf("线程正在执行\n"); sleep(1); } pthread_exit(NULL); } int main() { pthread_t thread_id; // 创建一个线程 pthread_create(&thread_id, NULL, thread_function, NULL); // 等待一段时间 sleep(3); // 发送取消请求 pthread_cancel(thread_id); // 等待线程结束 pthread_join(thread_id, NULL); printf("主线程结束\n"); return 0; }