获取线程ID:
函数原型:pthread_self();
形参列表 无参数,
返回值 返回值为当前的线程ID号,并且返回值数据类型为pthread_t ,该类型在系统中可能为不同的类型
在本人系统为unsigned long 类型。
ps:编译时需要链接第三方库 -l pthread
------------------------------------------------------------------------------------------------------------------------------------------------
创建一个进程:
函数原型:int ptherad_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
形参列表: thread为创建进程的ID号,定义一个pthread_t 类型的变量,在实参中加取址符,回写到变量中。
第二个参数 attr 为新线程的属性,默认类型NULL
第三个参数为新进程的入口函数,为函数名
第四个参数arg为传递给新线程的参数。
返回值: 成功返回0,失败返回-1.
-------------------------------------------------------------------------------------------------------------------------------------------------
退出线程:
函数原型:void pthread_exit(void *retval);
形参列表: retval全称return value,可以在其他线程调用pthread_join取得该返回值。
返回值: 无返回值。
---------------------------------------------------------------------------------------------------------------------------------------------------
线程等待以及资源的释放:
函数原型:int pthread_join(pthread_t tid, void **rval);
形参列表: tid 为需要等待的线程ID
rval为等待的线程的返回值。也就是pthread_exit函数的形参。
返回值:成功返回0,失败返回错误码。
----------------------------------------------------------------------------------------------------------------------------------------------------
线程的取消:
函数原型:int pthread_cancel(pthread_t thread);
形参列表: thread为取消的线程的ID号,
搭配int pthread_setcancelstate(int state, int *oldstate)函数可以修改线程对于cancel信号
的处理方式,state有两种值:PTHREAD_CANCEL_ENABLE(缺省:响应)、PTHREAD_CANCEL_DISABLE(忽略)
oldstate 如果不为NULL,则存入原来的cancel状态以便恢复。
搭配 int pthread_setcanceltype(int type, int *oldtype),可以设置取消的执行时机,
type有两种取值:PTHREAD_CANCEL_DEFFERED(下个取消点)、
PTHREAD_CANCEL_ASYCHRONOUS(立即取消)
第二个参数oldtype如果不为NULL,则存入原来的取消动作类型值
返回值: 成功返回0,失败返回-1
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
线程终止清理函数:
函数原型:void pthread_cleanup_push(void (*routine) (void *), void *arg)
void pthread_cleanup_pop(int execute)
必须成对出现,否则编译不会通过,原因是有一个宏定义,一个函数有左大括号,另一个右大括号。
参数列表: 第一个函数:routune为函数名,arg为传入函数的参数,执行后代表一个函数入栈。
第二个函数:execute可以为0和非0值 ,当为0是,仅仅在本线程调用pthread_exit以及其他函数对本线程
调用cancel函数时弹出清理函数并执行。
若为非0值,执行后都会弹出函数并执行。
无返回值
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
互斥锁函数:
互斥锁初始化有两种方式,一种是静态宏设置,一种是动态函数设置
静态锁设置 :快速静态锁:pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;普通锁,在嵌套锁时会出现死锁
递归锁:pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;可以嵌套上锁
检错锁:pthread_mutex_t errchkmutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;在出现嵌套锁时返回一个错误信息,不会死锁。
动态锁设置:int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
第一个参数为初始化的锁名称,第二个参数为锁的属性,对应快速锁,嵌套锁,检错锁。
可以定义一个pthread_mutexattr_t mutexattr; 通过修改mutexattr.__mutexkind = PTHREAD_MUTEX_RECURSIVE_NP修改为嵌套锁,
修改mutexattr.__mutexkind = PTHREAD_MUTEX_ERRORCHECK_NP修改为检错锁,使用NULL则缺省为快速锁。
对于锁的操作:加锁、解锁、测试加锁、销毁锁
加锁:int pthread_mutex_lock(pthread_mutex_t *mutex) 不管是哪种类型的锁,都不可能被两个线程
同时得到,必须等解锁。普通锁可以是同进程的任何线程,检错锁必须加锁者解锁,嵌套锁由加锁者解锁。
解锁:int pthread_mutex_unlock(pthread_mutex_t *mutex) 。对于快速锁,则解除锁定。对于嵌套锁,
使锁上的技术减一,表示上了两层。对于检错锁,如果锁是本线程加的,则解除锁,否则啥也不干。
测试加锁: int pthread_mutex_trylock(pthread_mutex_t *mutex) 使用测试加锁,则不会挂起阻塞。
销毁锁:int pthread_mutex_destroy(pthread_mutex_t *mutex); 销毁锁,意味着释放所占用的资源,而且要求锁处于开放状态。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
线程同步函数:条件变量和互斥锁结合,可以实现线程同步。
条件变量:静态创建和动态创建
静态创建:pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
动态创建:int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);
其属性在Linux Threads内没有实现,所以属性为NULL。
注销条件变量:int pthread_cond_destroy(pthread_cond_t *cond); 只有在没有线程在该条件变量等待时才
可以注销该变量。
等待条件变量: int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
该函数执行时会上锁并访问,假如没有收到信号,则阻塞,直至有信号到来,则解锁继续执行后续动作。
参数一:等待的条件变量 参数二:用于上锁的互斥锁。
还有一种计时等待,int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec
*abstime); 表示经历abstime时间后,即使没有信号到来,阻塞也被解除。
激发有两种:pthread_cond_signal(cond)激活一个等待该条件的线程。
而pthread_cond_broadcast()则激活所有等待线程。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
信号灯:
信号灯的初始化:int sem_init(sem_t *sem, int pshared, unsigned int value);
参数一:创建的信号灯 参数二:通常为0,表示单个进程多线程共享,没有实现用于多进程’
参数三:灯的数目,大于一为多元灯。
点灯:int sem_post(sem_t * sem); 灯加一,表示增加一个可访问的资源,只有灯值大于0,才可以访问公共资源。
灭灯:int sem_wait(sem_t * sem);灯减一,表示减少一个资源。
ps: int sem_trywait(sem_t * sem);为灭灯的非阻塞版。
读取灯值:int sem_getvalue(sem_t * sem, int * sval); 读取 sem 中的灯计数,存于*sval 中,并返回 0。
销毁信号灯:int sem_destroy(sem_t * sem);
被注销的信号灯 sem 要求已没有线程在等待该信号灯,否则返回-1,且置 errno 为 EBUSY。除此
之外,LinuxThreads 的信号灯注销函数不做其他动作。