Linux中线程的函数解析

来源:互联网 发布:ubuntu 14.04与16.04 编辑:程序博客网 时间:2024/06/06 03:50


获取线程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 的信号灯注销函数不做其他动作。





原创粉丝点击