在linux下,Pthread是一套通用的线程库,由POSIX提出,具有较好的移植性。
使用头文件<pthread.h>
线程基本操作
线程的创建与退出
pthead_create
1int pthread_create(pthread_t *thread, pthread_attr_t * attr, void *(*start_routine)(void *), void *arg);
传入参数:thread为线程标识符,attr为线程属性设置,start_routine为线程函数起始地址,arg为传给start_routine的参数。
返回值:0成功,-1失败。
pthread_exit
线程可以通过主动调用该函数结束自身。
值得注意不能使用exit
来结束当前线程,因为exit会终止进程,终止该进程中所有线程。
1void pthread_exit(void *retval)
传入参数:retval为调用者线程的返回值。
pthread_join
该函数用于将当前线程挂起,值得被等待的线程结束为止,当函数返回时,被等待线程的资源就被收回。
1int pthread_join ((pthread_t th, void 参考资料**thread_return))
传入参数:th为等待线程的标识符,thread_return为用户定义的指针,用于存储被等待线程的返回值(不为NULL)时。
修改线程的属性资源
参考资料: 多线程属性pthread_attr详解
在thread_create函数中,我们可以自定义线程的属性。线程主要有如下的一些属性:绑定属性、分离属性、堆栈地址、堆栈大小、优先级。默认的属性是非绑定、非分离、1M的堆栈、与父进程优先级相同。
pthread_attr_init
线程属性的设置通常先调用该函数进行初始化,之后再调用相应的属性设置函数进行设置。
1int pthread_attr_init(pthread_attr_t *attr)
传入参数: attr线程属性
返回值:成功0,失败-1
pthread_attr_setscope
1int pthread_attr_getscope( const pthread_attr_t * attr, int * scope );
2int pthread_attr_setscope( pthread_attr_t*, int scope );
传入参数:
- attr线程属性
- scope:PTHREAD_SCOPE_SYSTEM 绑定(系统级竞争资源),PTHREAD_SCOPE_PROCESS 非绑定(进程内竞争资源)
pthread_attr_setdetachstate
线程的分离状态决定一个线程以什么方式结束自己。默认情况下为非分离,此时原有的线程等待新线程的结束,只有当pthread_join返回时,新线程才算终止。而在分离状态下,新线程一旦运行结束马上释放资源。
需要注意,在分离状态下,如果某一个进程运行的飞快,在pthread_create函数返回前就终止了,它终止后就可能将线程号和系统资源给其他线程使用,这时调用pthread_create就可能返回错误的线程号。
1int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
detachstate: PTHREAD_CREATE_DETACHED 分离, PTHREAD _CREATE_JOINABLE 非分离
调度策略的获取/设置
1int pthread_attr_getschedpolicy(const pthread_attr_t *, int * policy)
2int pthread_attr_setschedpolicy(pthread_attr_*, int policy)
传入参数:policy为调度策略,有若干种可能的情况:
- SCHED_FIFO
- SCHED_RR (轮转法)
- SHCED_OTHER
前两种方法均支持优先级的使用,优先级从1-99,数值越大优先级越高。
优先级的获取/设置/最值查询
1int pthread_attr_getschedparam(const pthread_attr_t *,struct sched_param *);
2int pthread_attr_setschedparam(pthread_attr_t *,const struct sched_param *);
默认的结构大概是这样
1struct sched_param{
2 int sched_priority;
3};
可以通过如下两个函数获取系统支持的优先级的最值
1int sched_get_priority_max( int policy );
2int sched_get_priority_min( int policy );
线程访问控制
由于线程共享进程资源,因而需要考虑资源访问的问题。
mutex互斥锁
互斥锁的类型
参考资料 九、Linux下线程互斥锁类型及属性
-
PTHREAD_MUTEX_NORMAL: 标准互斥锁:第一次上锁成功,第二次上锁会阻塞。 描述: 此类型的互斥锁不会检测死锁。如果线程在不首先解除互斥锁的情况下尝试重新锁定该互斥锁,则会产生死锁。尝试解除由其他线程锁定的互斥锁会产生不确定的行为。如果尝试解除锁定的互斥锁未锁定,则会产生不确定的行为。
-
PTHREAD_MUTEX_ERRORCHECK: 检错互斥锁:第一次上锁成功,第二次上锁会出错。
描述: 此类型的互斥锁可提供错误检查。如果线程在不首先解除锁定互斥锁的情况下尝试重新锁定该互斥锁,则会返回错误。如果线程尝试解除锁定的互斥锁已经由其他线程锁定,则会返回错误。如果线程尝试解除锁定的互斥锁未锁定,则会返回错误。
-
PTHREAD_MUTEX_RECURSIVE:递归互斥锁:第一次上锁成功,第二次上锁也会成功,内部计数。 描述:操作操作 如果线程在不首先解除锁定互斥锁的情况下尝试重新锁定该互斥锁,则可成功锁定该互斥锁。 与 PTHREAD_MUTEX_NORMAL 类型的互斥锁不同,对此类型互斥锁进行重新锁定时不会产生死锁情况。多次锁定互斥锁需要进行相同次数的解除锁定才可以释放该锁,然后其他线程才能获取该互斥锁。如果线程尝试解除锁定的互斥锁已经由其他线程锁定,则会返回错误。 如果线程尝试解除锁定的互斥锁未锁定,则会返回错误。
-
PTHREAD_MUTEX_DEFAULT:默认互斥锁:同标准的互斥锁 描述: 如果尝试以递归方式锁定此类型的互斥锁,则会产生不确定的行为。对于不是由调用线程锁定的此类型互斥锁,如果尝试对它解除锁定,则会产生不确定的行为。对于尚未锁定的此类型互斥锁,如果尝试对它解除锁定,也会产生不确定的行为。允许在实现中将该互斥锁映射到其他互斥锁类型之一。
对互斥锁的操作
互斥锁的创建
1int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
mutexattr缺省时默认创建快速互斥锁(PTHREAD_MUTEX_DEFAULT)
互斥锁的操作
1int pthread_mutex_lock(pthread_mutex_t *mutex)
2int pthread_mutex_trylock(pthread_mutex_t *mutex)
3int pthread_mutex_unlock(pthread_mutex_t *mutex,)
4int pthread_mutex_destroy(pthread_mutex_t *mutex,)
(望文生义即可.jpg)
信号量线程控制
功能参见OS教材即可。
头文件
#include <semaphore.h>
基本操作
1int sem_init(sem_t *sem, int pshared, unsigned int value)
传入参数:
- sem信号量
- pshared决定信号量能在几个进程间共享,由于目前linux还不能实现进程间信号量的共享,所以该值只能取1
- value信号初始值
1int sem_wait(sem_t *sem)
2int sem_trywait(sem_t *sem)
3int sem_post(sem_t *sem)
4int sem_getvalue(sem_t *sem)
5int sem_destroy(sem_t *sem)
望文生义即可。