Pthreads (POSIX threads)
- POSIX线程标准:定义了创建和操纵线程的一套API
- Pthreads API中函数(以"pthread_"开头)分为四类:
– 线程管理:创建进程,等待线程,查询线程状态等
– 互斥锁(Mutex):创建、摧毁、锁定、解锁、设置属性等操作
– 条件变量(Condition Variable):创建、摧毁、等待、通知、设置与查询属性等操作
– 使用了互斥锁的线程间的同步管理
相关函数(pthread.h)
线程操纵函数
-
创建线程
pthread_create(thread, attr, start_routline, arg);参数 含义 类型 thread 指向线程标识指针 thread_t * attr 用于设置线程属性,可为NULL start_routline 线程运行函数的起始地址 (void *)(*)(void *) arg 运行函数的参数,必须通过把引用作为指针强制转换为void类型进行传递(可为NULL),若要传递多个参数可使用结构体 void * 注:线程创建成功时,该函数返回0,反之不为0;
-
终止当前线程
pthread_exit() -
请求中断另一个线程
pthread_cancel():被请求中断的线程会继续运行,直至到达某个取消点(Cancellation Point)。取消点是线程检查是否被取消并按照请求进行动作的一个位置。POSIX 的取消类型(Cancellation Type)有两种,一种是延迟取消(PTHREAD_CANCEL_DEFERRED),这是系统默认的取消类型,即在线程到达取消点之前,不会出现真正的取消;另外一种是异步取消(PHREAD_CANCEL_ASYNCHRONOUS),使用异步取消时,线程可以在任意时间取消。系统调用的取消点实际上是函数中取消类型被修改为异步取消至修改回延迟取消的时间段。几乎可以使线程挂起的库函数都会响应CANCEL信号,终止线程,包括sleep、delay等延时函数。 -
阻塞当前的线程,直到另一个线程运行结束
pthread_join() -
根据返回值判断线程死活
pthread_kill():向指定ID的线程发送一个信号,如果线程不处理该信号,则按照信号默认的行为作用于整个进程。信号值0为保留信号,作用是根据函数的返回值判断线程是不是还活着。
线程属性函数
- 初始化线程属性变量
pthread_attr_init() - 设置线程属性变量的detachstate属性 (决定线程在终止时是否可以被joinable)
pthread_attr_setdetachstate(): - 删除线程属性 (用无效值覆盖)
pthread_attr_destory()
工具函数
-
比较两线程的标识号
pthread_equal() -
分离线程
ptread_detach() -
查询自身线程标识号
pthread_self()
实例
#include <iostream>
#include <pthread.h>
using namespace std;
#define N 3 //线程个数
void * thread_content(void *args)
{
cout << "创建第" << *((int *) args) + 1 << "个线程,线程ID:" << pthread_self() << endl;
pthread_exit(NULL); // 结束当前线程
}
int main()
{
pthread_t tids[N]; // 线程数组
int args[N], re;
for(int i = 0; i < N; i++)
{
args[i] = i;
re = pthread_create(&tids[i], NULL, thread_content, (void *)&args[i]); // 创建线程
if(re)
{
cout << "无法创建线程," << re;
exit(-1);
}
/*
void *r;
pthread_join(tids[i], &r); // 阻塞当前线程,等待指定(上一个)线程完成
*/
}
return 0;
}
一般情况下,创建线程任务速度较运行线程任务快,快到几乎每个线程相当于是同时运行的,所以输出的结果会像下面这样,虽然该输出的都属输出了(包括换行)显示却是乱的
可调用pthread_join();阻塞线程,直到上一个线程完成
Pthreads参考:https://zh.wikipedia.org/wiki/POSIX线程
Windows API:https://www.runoob.com/w3cnote/cpp-multithread-demo.html