Linux线程初步介绍

以下内容引述至《Linux/Unix系统编程手册》

线程

Pthread API 定义了一干数据类型

数据类型描述
pthread_t线程ID
pthread_mutex_t互斥对象
pthread_mutexattr_t互斥属性对象
pthread_cond_t条件变量

pthread 函数返回值
从系统调用和库函数中返回状态,传统的做法是:返回0表示成功,返回-1表示失败,并设置errno以标识错误原因。pThread API则反其道行之,返回0表示成功,返回一正值表示失败。这个值与errno中的值含义相同。

编译

编译pThread API的程序时,需要设置 cc -pthread的编译选项,使用该选项的效果如下:

  • 定义_REENTRANT预处理宏,这会公开对少数可重入函数的声明;
  • 程序会与libpthread进行连接(等价于-lpthread)

线程创建

#include <pthread.h>
int pthread_create(pthread_t* thread, const pthread_attr_t *attr, 
				void* (*start)(void*), void* arg);

将参数arg声明为void类型,意味着可以将指向任意对象的指针传递给start()函数;
严格来说,对于int与void
之间相互强制转换的后果,C语言标准未加以定义。start的返回值类型为void*,对其使用方式与参数arg相同。

线程终止

线程终止的方式

  • 线程start函数执行return语句并返回指定值
  • 线程调用pthread_exit()
  • 调用pthread_cancel取消线程
  • 任意线程调用了exit(),或者主线程执行了return语句
#include <pthread.h>
void pthread_exit(void *retval);

参数retval指定了线程的返回值。
如果主线程调用了pthread_exit(),而非调用exit()或者执行return语句,那么其他线程将继续运行。

线程ID

进程内部每个线程有一个唯一标志,线程ID。但是多进程下,线程ID不一定唯一。
线程ID返回给pthread_create()的调用者,一个线程可以通过pthread_self()来获取自己线程的ID

#include <pthread.h>
pthread_t pthread_self(void);

int pthread_equal(pthread_t t1, pthread_t t2);

不同于gettid函数,gettid是内核分配的数字

连接已终止的线程

函数pthread_join等待由thread标志的线程终止(如果线程已经终止,pthread_join()会立即返回)

#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);

如果向pthread_join传入一个之前已经连接过的线程ID,将会导致无法预知的行为。
若线程未分离,则必须使用pthread_join()来进行连接。如果未能连接,那么线程终止时将产生僵尸线程,类似于僵尸进程。除了浪费系统资源外,僵尸线程若积累过多,应用将再也无法创建新的线程。
pthread_join与waitpid的差别

  • 线程之间的关系是对等的,进程中的任意线程均可以调用pthread_join与该进程的任何其他线程连接起来。
  • 无法“连接任意线程”也不能以非阻塞方式进行连接,使用条件变量可以实现类似的功能。

PS: join(self)会发生死锁

if(!pthread_equal(tid, pthread_self()){
	pthread_join(tid, nullptr);
}

线程分离

默认情况下,线程是可连接的(joinable)
当不关心线程的返回状态时,只是希望系统在线程终止的时候能够自动清理并移除,可以调pthread_detach并向thread参数传入指定线程的标识符,将线程标志于分离的状态

#include <pthread.h>
int pthread_detach(pthread_t thread);

其他线程调用了exit(),或者主线程执行了return语句时,即便遭到分离的线程也还是会收到影响。不管线程是分离还是可连接状态,进程的所有线程会立即终止。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值