线程相关函数(1)-pthread_create(), pthread_join(), pthread_exit(), pthread_cancel() 创建取消线程
一. pthread_create()
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
pthread_t *thread: 传递一个pthread_t变量地址进来,用于保存新线程的tid(线程ID)
const pthread_attr_t *attr: 线程属性设置,如使用默认属性,则传NULL
void *(*start_routine) (void *): 函数指针,指向新线程应该加载执行的函数模块
void *arg: 指定线程将要加载调用的那个函数的参数
返回值:成功返回0,失败返回错误号。以前学过的系统函数都是成功返回0,失败返回-1,而错误号保存在全局变量errno中,而pthread库的函数都是通过返回值返回错误号,虽然每个线程也都有一个errno,但这是为了兼容其它函数接口而提供的,pthread库本身并不使用它,通过返回值返回错误码更加清晰。
二.pthread_join()
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
pthread_t thread: 回收线程的tid
void **retval: 接收退出线程传递出的返回值
返回值:成功返回0,失败返回错误号
注意:
调用该函数的线程将挂起等待,直到id为thread的线程终止。thread线程以不同的方法终止,通过pthread_join得到的终止状态是不同的,总结如下:
如果thread线程通过return返回,retval所指向的单元里存放的是thread线程函数的返回值。
如果thread线程被别的线程调用pthread_cancel异常终止掉,retval所指向的单元里存放的是常数PTHREAD_CANCELED。
如果thread线程是自己调用pthread_exit终止的,retval所指向的单元存放的是传给pthread_exit的参数。
如果对thread线程的终止状态不感兴趣,可以传NULL给retval参数。
三.pthread_exit()
#include <pthread.h>
void pthread_exit(void *retval);
void *retval: 线程退出时传递出的参数,可以是退出值或地址,如是地址时,不能是线程内部申请的局部地址。
注意和exit函数的区别,任何线程里exit导致进程退出,其他线程未工作结束,主线程退出时不能return或exit。需要注意,pthread_exit或者return返回的指针所指向的内存单元必须是全局的或者是用malloc分配的,不能在线程函数的栈上分配,因为当其它线程得到这个返回指针时线程函数已经退出了。
四.pthread_cancel()
#include <pthread.h>
int pthread_cancel(pthread_t thread);
定义在Linux的pthread库中常数PTHREAD_CANCELED的值是-1。可以在头文件pthread.h中找到它的定义:
#define PTHREAD_CANCELED ((void *) -1)
五.示例
#include <pthread.h>
#include <stdio.h>
#include <unistd.h> void *thr_fn1(void *arg)
{
printf("thread 1 returning\n");
return (void*);
} void *thr_fn2(void *arg)
{
printf("thread 2 exiting\n");
pthread_exit((void*));
} void *thr_fn3(void *arg)
{
while() {
printf("thread 3 writing\n");
sleep();
}
} int main()
{
pthread_t tid;
void *retval; pthread_create(&tid, NULL, thr_fn1, NULL);
pthread_join(tid, &retval);
printf("thread 1 exit code %d\n", (int)retval); pthread_create(&tid, NULL, thr_fn2, NULL);
pthread_join(tid, &retval);
printf("thread 2 exit code %d\n", (int)retval); pthread_create(&tid, NULL, thr_fn3, NULL);
sleep();
// 调用pthread_cancel函数取消第三个线程
pthread_cancel(tid);
// 如果线程是通过pthread_cancel异常终止掉,retval所指向的单元里存放的是常数PTHREAD_CANCELED
pthread_join(tid, &retval);
printf("thread 3 exit code %d\n", (int)retval); return ;
}
运行结果:
thread 1 returning
thread 1 exit code 1
thread 2 exiting
thread 2 exit code 2
thread 3 writing
thread 3 writing
thread 3 writing
thread 3 exit code -1
线程相关函数(1)-pthread_create(), pthread_join(), pthread_exit(), pthread_cancel() 创建取消线程的更多相关文章
- linux下pthread_cancel无法取消线程的原因【转】
转自:http://blog.csdn.net/huangshanchun/article/details/47420961 版权声明:欢迎转载,如有不足之处,恳请斧正. 一个线程可以调用pthrea ...
- linux下pthread_cancel无法取消线程的原因
一个线程能够调用pthread_cancel终止同一进程中的还有一个线程,可是值得强调的是:同一进程的线程间,pthread_cancel向还有一线程发终止信号.系统并不会立即关闭被取消线程,仅仅有在 ...
- linux c 线程相关函数
线程相关函数(1)-pthread_create(), pthread_join(), pthread_exit(), pthread_cancel() 创建取消线程 一. pthread_creat ...
- java线程池及创建多少线程合适
java线程池 1.以下是ThreadPoolExecutor参数完备构造方法: public ThreadPoolExecutor(int corePoolSize,int maximumPoolS ...
- {Python之线程} 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Threading模块 九 锁 十 信号量 十一 事件Event 十二 条件Condition(了解) 十三 定时器
Python之线程 线程 本节目录 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Thr ...
- Java线程状态、线程start方法源码、多线程、Java线程池、如何停止一个线程
下面将依次介绍: 1. 线程状态.Java线程状态和线程池状态 2. start方法源码 3. 什么是线程池? 4. 线程池的工作原理和使用线程池的好处 5. ThreadPoolExecutor中的 ...
- linux线程相关函数接口
以下内容转自网络 索引:1.创建线程pthread_create2.等待线程结束pthread_join3.分离线程pthread_detach4.创建线程键pthread_key_create5.删 ...
- Linux 进程与线程一(创建-关闭线程)
进程是一个实体.每一个进程都有他自己的内存地址段(heap,stack等等) 进程是执行中的程序. 程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的实体. 进程是操作系统中最基 ...
- 线程相关函数(POSIX线程):
创建单个线程 #include <pthread.h> // 若成功返回0,出错返回正的Exxx值 int pthread_create(pthread_t *tid, // 每个线程在进 ...
随机推荐
- Apache的commons工具类
package cn.zhou; import java.io.File; import java.io.IOException; import org.apache.commons.io.FileU ...
- 用MyEclipse自带工具生成WebService客户端代码
本文章主要是介绍如何利用已经发布了的Webservice的wsdl来自动生成java的客户端代码.注意:本方法需要你采用的java版本是1.5或者以上的版本,采用MyEclipse来自动生成代码. w ...
- vue axios 封装(一)
封装一: 'use strict' import axios from 'axios' import qs from 'qs' import NProgress from 'nprogress' im ...
- HttpRequest,WebRequest,HttpWebRequest,WebClient,HttpClient 之间的区别
HttpRequest,WebRequest,HttpWebRequest,WebClient,HttpClient 今天我们来聊一下他们之间的关系与区别. HttpRequest 类 .NET Fr ...
- 如何在虚拟机下配置centOS7
链接地址:https://baijiahao.baidu.com/s?id=1597320700700593557&wfr=spider&for=pc
- codeforces492C
Vanya and Exams CodeForces - 492C Vanya wants to pass n exams and get the academic scholarship. He w ...
- 洛谷 P1126 机器人搬重物
题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径 $1.6 米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个 N×MN \times MN×M ...
- pip 使用
PIP的使用 作用 管理python的标准第三方库 安装 sudo apt-get install python3-pip 常用命令 [1] 安装软件包 pip3 install [package] ...
- MT【247】恒成立画图像
若$|x^2+|x-a|+3a|\le2$对任意$x\in[-1,1]$恒成立,则$a$ 的取值范围_____ 分析:转化为$f(x)=|x-a|+3a$的图像夹在$y=-2-x^2$与$y=2-x^ ...
- android 异常信息The specified child already has a parent. You must call removeView() on the child's parent first. 的处理方法
[Android异常信息]: The specified child already has a parent. You must call removeView() on the child's p ...