Linux中关于线程的操作函数API(pthread_create/pthread_mutex/pthread_cond)

一、线程的创建与销毁:

函数API:

#include <pthread.h>

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
				   void *(*start_routine)(void *), void *arg);

pthread_t pthread_self(void);

void pthread_exit(void *retval);

int pthread_cancel(pthread_t tid);

int pthread_join(pthread_t tid, void **retval);

int pthread_detach(pthread_t tid);

各个函数的返回值:

int pthread_create:
	成功返回0, 失败返回错误码:EAGAIN/EINVAL/EPERM
	(1)EAGAIN:没有足够的资源创建线程;
	(2)EINVAL:attr线程属性参数不正确;
	(3)EPERM:no permission,没有权限

void pthread_exit(void *retval):
	无返回值,通过参数*retval返回一个字符串,
	返回到给正在调用pthread_join等待它的线程
	(返回到pthread_join第二个参数中)

int pthread_cancel(pthread_t tid):
	成功返回0,失败返回错误码:ESRCH
	(1)ESRCH:No thread with the ID could be found. 
	参数thread指定的线程找不到,不存在


int pthread_join(pthread_t tid, void **retval):
	成功返回0,失败返回错误码:EDEADLOCK/EINVAL/ESRCH
	(1)EDEADLOCK:死锁,例如两个线程互相join等待对方
	   注:pthread_join是一个阻塞函数,要一直等到其所等待的线程结束后才能继续向下执行,因此如果发生两个线程互相join等待彼此时是会发生死锁的
	(2)EINVAL:参数tid所指定的线程不是joinable态(tid若处于detach则不能当做被join等待的对象)
	   或者:另有一个线程正在join等待本线程,及join不能嵌套
	(3)ESRCH:参数tid所指定的线程找不到,即这个线程不存在。
	
int pthread_detach(pthread_t tid):
	成功返回0,失败返回错误码:EINVAL/ESRCH
	(1)EINVAL:there is a not a joinable thread. 不是joinable的线程,不能调用detach
	(2)ESRCH:No thread with the ID could be found. 参数tid指定的线程不存在

一个线程终止(被终止)的方式:

(1)线程内调用pthread_exit:
如果不带参数:pthread_exit(NULL); 则直接退出;
如果带参数:pthread_exit(*str);  则将字符串str拷贝到 pthread_join(tid, &ptr)的ptr中

(2)其它线程调用pthread_cancel终止本线程:
pthread_cancel(tid);
线程调用pthread_cancel函数给tid线程发送一个cancel终止信号,tid线程收到终止信号后并不会立即终止,而是要看tid线程对cancel信号的处理方式:
忽略 / 立即终止 / 运行至取消点
(取消点:根据POSIX的定义,所有可能会引起线程阻塞的系统调用都是取消点,
例如:pthread_join、pthread_cond_wait、read、write、sem_wait 等)

二、线程互斥锁和条件变量:

#include <pthread.h>

//创建:
int pthread_mutex_init(pthread_mutex_t *restrict_mutex, 
					const pthread_mutexattr_t *restrict_attr);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
//销毁:
int pthread_mutex_destroy(pthread_mutex_t *mutex);
//加锁:
int pthread_mutex_lock(pthread_mutex_t *mutex);
//解锁:
int pthread_mutex_unlock(pthread_mutex_t *mutex);


//初始化信号量:
int pthread_cond_init(pthread_cond_t *cond, 
					pthread_cond_attr_t *cond_attr);
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
//销毁信号量:
int pthread_cond_destroy(pthread_cond_t *cond);
//等待信号量:
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
//唤醒一个等待队列中的线程:
int pthread_cond_signal(pthread_cond_t *cond);
//唤醒等待队列中的所有线程:
int pthread_cond_broadcast(pthread_cond_t *cond);

关于线程信号量的深入理解:

(1)pthread_cond_wait 实现了一个阻塞队列,每个等待mutex的线程都放在这个等待队列中;
所以 pthread_cond_signal 就是从等待队列中取出一个线程唤醒,pthread_cond_broadcast 则是将等待队列中的所有线程全部唤醒。
(2)pthread_cond_wait 函数内部先对 mutex unlock 解锁,然后再对 mutex lock 加锁。

猜你喜欢

转载自blog.csdn.net/ArtAndLife/article/details/110941481