pthread_create()的帮助文档里面,明确指出,一个线程的终止有如下的四种方式:
* 本线程中调用pthread_exit(),同一进程里面调用pthread_join()的其他线程可以获取该线程的退出值。
* 本线程的线程函数start_routine执行结束返回。
* 本线程被pthread_cancel()取消。
* 本线程所在的进程退出。
pthread_exit(), 原型:
void pthread_exit(void *retval);
该函数在线程中的作用,与exit()在进程中的作用类似。执行到pthread_exit(),线程将会直接终止,并使用pthread_exit的参数作为线程的退出状态值。如果线程是joinable的,其线程ID和退出状态值将一直保留到调用进程中的某个其他线程调用pthread_join函数。指针retval不能指向局部于调用线程的对象,因为线程终止时这些对象也消失。
pthread_cancel(),原型:
int pthread_cancel(pthread_t thread);
pthread_cancel()发送一个取消请求给目标线程,该函数需要目标线程配合。目标线程如何操作,取决于该线程的可撤销状态及类型(cancelability state and type)。
可撤销状态有两个值:PTHREAD_CANCEL_ENABLE,PTHREAD_CANCEL_DISABLE。该状态可以通过pthread_setcancelstate()函数来修改。这个状态决定该线程是否处理取消请求。如果PTHREAD_CANCEL_ENABLE,则处理取消请求,PTHREAD_CANCEL_DISABLE,则不处理取消请求。
可撤销类型同样也有两个值:PTHREAD_CANCEL_DEFERRED,PTHREAD_CANCEL_ASYNCHRONOUS。该类型可以通过pthread_setcanceltype()函数来修改。可撤销状态为PTHREAD_CANCEL_ENABLE时,可撤销类型值才会被判断。PTHREAD_CANCEL_ASYNCHRONOUS 立即执行取消信号,PTHREAD_CANCEL_DEFERRED 运行到下一个取消点然后退出线程。
PTHREAD_CANCEL_DEFERRED情形下,pthread_cancel()给目标线程设置一个取消标志。目标线程在运行中的某些地方会查看自己是否存在取消请求,如果有,就立刻终止执行后继代码并退出。这些查看是否存在取消请求的地方,称之为取消点(Cancelation-point)。
下面的代码,是在suse linux中的pthread_cancel编程指南中例子的基础上修改得到:
#include <pthread.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#define handle_error_en(en, msg) \
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
static void * thread_func(void *ignored_argument)
int s;
pthread_t *pthr = (pthread_t *)ignored_argument;
/* Disable cancellation for a while, so that we don't
immediately react to a cancellation request */
s = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
if (s != 0)
handle_error_en(s, "pthread_setcancelstate");
printf("thread_func(id %u (0x%x)): started; cancellation disabled\n",
(unsigned int)(*pthr), (unsigned int)(*pthr));
sleep(5);
printf("thread_func(id %u (0x%x)): about to enable cancellation\n",
(unsigned int)(*pthr), (unsigned int)(*pthr));
s = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
if (s != 0)
handle_error_en(s, "pthread_setcancelstate");
/* sleep() is a cancellation point */
sleep(10); /* Should get canceled while we sleep */
/* Should never get here */
printf("thread_func(id %u (0x%x)): not canceled!\n",
(unsigned int)(*pthr), (unsigned int)(*pthr));
return NULL;
int main(void)
pthread_t thr1;
pthread_t thr2;
void *res;
int s;
/* Start a thread and then send it a cancellation request */
s = pthread_create(&thr1, NULL, &thread_func, (void*)&thr1);
if (s != 0)
handle_error_en(s, "pthread_create 1");
s = pthread_create(&thr2, NULL, &thread_func, (void*)&thr2);
if (s != 0)
handle_error_en(s, "pthread_create 2");
sleep(2); /* Give thread a chance to get started */
printf("main(): sending cancellation request\n");
s = pthread_cancel(thr1);
if (s != 0)
handle_error_en(s, "pthread_cancel");
/* Join with thread to see what its exit status was */
s = pthread_join(thr1, &res);
if (s != 0)
handle_error_en(s, "pthread_join");
if (res == PTHREAD_CANCELED)
printf("main(): thread 1 was canceled\n");
printf("main(): thread 1 wasn't canceled (shouldn't happen!)\n");
s = pthread_join(thr2, &res);
if (s != 0)
handle_error_en(s, "pthread_join");
if (res == PTHREAD_CANCELED)
printf("main(): thread 2 was canceled\n");
printf("main(): thread 2 wasn't canceled (shouldn't happen!)\n");
exit(EXIT_SUCCESS);
别被名字吓到,pthread_kill可不是kill,而是向线程发送signal。还记得signal吗,大部分signal的默认动作是终止进程的运行,所以,我们才要用signal()去抓信号并加上处理函数。
int pthread_kill(pthread_t thread, int sig);
向指定ID的线程发送sig信号,如果线程代码内不做处理,则按照信号默认的行为影响整个进程,也就是说...
linux终止线程
正常情况下,线程一旦创建便从指定函数开始执行直到该函数返回。一旦该函数返回,这些线程便自行终止。线程也可以在执行的途中通过调用pthread_exit()终止自己的执行。实际上,非初始线程(这里只main函数的线程)从开始函数返回是返回到线程库中,由线程库隐含地调用函数pthread_exit(),并用开始函数的返回值作为线程的出口状态。但是,初始线程则不然。初始线程如果也调用相同的开始函数,在这个函数没有明显调用pthread_exit()的情况下,它将正常返回到其调用点。
线程终止并
还记得signal吗,大部分signal的默认动作是终止进程的运行,所以,我们才要用signal()去抓信号并加上处理函数。向指定ID的线程发送sig信号,如果线程代码内不做处理,则按照信号默认的行为影响整个进程,也就是说,如果你给一个线程发送了SIGQUIT,但线程却没有实现signal处理函数,则整个进程退出。所以,如果int sig的参数不是0,那一定要清楚到底要干什么,而且一定要实现线程的信号处理函数,否则,就会影响整个进程。所以,pthread_kill(threadid,0)就很有用啦。
文章目录一、线程二、线程分离回收回收资源:1. 使用pthread_join()函数进行回收2. 使用线程分离属性使系统自动回收:获取线程返回码线程取消线程终止释放、清理三、信号处理信号发送信号接收可靠信号&&不可靠信号四、多线程信号处理
本课题环境:ubuntu16、glibc 2.23
一、线程
概念:线程是操作系统能够调度和执行的基本单位,在Linux中也被称之为轻量级进程
线程定义在pthread.h文件中,那么要创建线程就要进行引用预编译,线程创建函数定义如下:
#includ
1. 在线程池内部,当我们把一个任务丢给线程池去执行,线程池会调度工作线程来执行这个任务的 run 方法,run 方法正常结束,也就意味着任务完成了。
所以线程池中的工作线程是通过同步调用任务的 run()方法并且等待 run 方法返回后, 再去统计任务的完成数量。
2. 如果想在线程池外部去获得线程池内部任务的执行状态,有几种方法可以实现。
线程池提供了一个 isTerminated()方法,可以判断线程池的运行状态,我们可以循环判断 isTerminated()方法的
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
//thread: 接收创建的线程的 ID
//attr: 指定线程的属性 (一般传空)
//start_routine: 指定线程函数
//arg: 给线程函数传递的参数
//成功返回 0, 失败返回错误码
```...
基于进程的多任务处理是程序的并发执行。
基于线程的多任务处理是同一程序的片段并发执行
假设您使用的是 Linux 操作系统,我们要使用 POSIX 编写多线程 C++ 程序。POSIX Threads 或 Pthreads 提供的 API 可在多种类 Unix POSIX 系统上可用,比如 FreeBSD、NetBSD、GNU/Linux、Mac OS X 和 Sola
说在前面:与线程相关的函数构成了一个完整的系列,绝大多数函数的名字都是以“pthread_”打头的,要想使用这些函数,要通过引入头文,链接这些线程函数库时要使用编译器命令的“-lpthread”选项创建线程//创建一个新的线程
int pthread_create(pthread_t *threade,const pthreade_attr_t *attr,void *(*start_rout