Linux中线程的函数解析

本文详细介绍了线程管理的基本操作,包括线程的创建、退出、等待、取消及清理等,并深入探讨了线程间的同步机制,如互斥锁、条件变量和信号灯的使用方法。


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





<think>嗯,用户的问题是关于Linux线程相关的函数解析,需要详细的信息。首先我得回忆一下自己之前学过的Linux线程知识。记得线程管理主要用到pthread库,里面有很多函数比如创建线程的pthread_create,还有终止、同步之类的函数。 用户提供的引用里有几个关键点。引用1提到了pthread_create的参数,线程ID、属性、回调函数和参数。引用3和4讨论了线程的分离属性,分离状态下线程结束后自动释放资源,不需要join。而默认情况下需要pthread_join来回收资源,否则会有资源泄漏。这点很重要,用户可能需要注意避免内存泄漏的问题。 接下来,我需要把常用的线程函数整理出来,比如创建、终止、等待、分离等。每个函数的参数和返回值要解释清楚。比如pthread_create返回0表示成功,错误码则通过返回值传递,而不是errno,这点容易出错,需要特别说明。 然后,线程属性相关的函数,比如设置分离属性,用pthread_attr_setdetachstate,还有初始化销毁属性对象。这些函数在需要设置线程属性的时候使用,比如想让线程一开始就是分离的。 还有线程ID获取和比较的函数,pthread_self和pthread_equal。可能用户在多线程中需要识别不同的线程,这时候这些函数就派上用场了。 线程终止的方式除了return,还可以用pthread_exit,或者被其他线程取消。pthread_cancel的使用需要注意,目标线程可能设置了取消点,或者异步取消,可能会有资源清理的问题,所以最好用pthread_cleanup_push和pop来处理。 此外,线程同步的函数,比如互斥锁和条件变量,虽然用户的问题可能主要关注基础函数,但提到这些可以作为相关问题的一部分,或者简要提及。 用户提供的引用中有提到eventfd函数,不过这可能和线程的关系不大,更多用于进间通信或者事件通知,但用户的问题集中在线程函数,所以可能不需要深入讨论这个。 需要确保回答的结构清晰,分点列出每个函数,说明功能、参数、注意事项。例如,pthread_create的示例代码可以帮助用户理解如何使用。还要注意提到的分离属性的问题,比如如果线程结束太快,可能在pthread_create返回前就终止,导致得到错误的线程ID,这点需要提醒用户注意。 另外,用户可能对错误处理不太清楚,比如pthread函数返回错误码而不是设置errno,所以在检查返回值时要用strerror输出错误信息。 最后,生成的相关问题需要考虑用户可能的后续疑问,比如线程同步、资源竞争、死锁避免,或者具体的函数使用场景,比如如何正确使用pthread_join,或者分离线程的应用场景。</think>### Linux线程相关函数解析 #### 一、线程创建与终止 1. **pthread_create** 功能:创建新线程 函数原型: ```c int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg); ``` - `thread`:输出参数,存储新线程ID - `attr`:线程属性(默认属性可设为`NULL`) - `start_routine`:线程入口函数 - `arg`:传递给入口函数的参数 - 返回值:0表示成功,错误码表示失败[^1][^2] ```c // 示例:创建线程执行打印任务 void* print_msg(void *msg) { printf("%s\n", (char*)msg); return NULL; } pthread_t tid; char *message = "Hello Thread"; pthread_create(&tid, NULL, print_msg, message); ``` 2. **pthread_exit** 功能:显式终止当前线程 函数原型: ```c void pthread_exit(void *retval); ``` - `retval`:线程返回值(可通过`pthread_join`获取)[^4] --- #### 二、线程控制 1. **pthread_join** 功能:阻塞等待线程终止并回收资源 函数原型: ```c int pthread_join(pthread_t thread, void **retval); ``` - `thread`:目标线程ID - `retval`:接收线程返回值指针的地址 - 注意:对已分离的线程调用会返回`EINVAL`错误[^3] 2. **pthread_detach** 功能:设置线程为分离状态(自动回收资源) 函数原型: ```c int pthread_detach(pthread_t thread); ``` - 典型应用场景:不需要获取线程返回值的场景[^3][^4] --- #### 三、线程属性控制 1. **属性对象初始化/销毁** ```c int pthread_attr_init(pthread_attr_t *attr); int pthread_attr_destroy(pthread_attr_t *attr); ``` 2. **设置分离属性** ```c int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); ``` - `detachstate`:`PTHREAD_CREATE_JOINABLE`(默认)或`PTHREAD_CREATE_DETACHED` - 示例:创建即分离的线程 ```c pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(&tid, &attr, thread_func, NULL); ``` --- #### 四、线程标识 1. **pthread_self** 功能:获取当前线程ID ```c pthread_t pthread_self(void); ``` 2. **pthread_equal** 功能:比较两个线程ID是否相同 ```c int pthread_equal(pthread_t t1, pthread_t t2); ``` --- #### 五、错误处理特性 - 所有pthread函数返回值直接为错误码(非传统Unix errno机制) - 示例: ```c if (pthread_create(&tid, NULL, func, NULL) != 0) { fprintf(stderr, "Thread creation error: %s\n", strerror(retval)); } ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值