线程
头文件
#include <pthread.h>
获取线程号
pthread_t pthread_self(void); // 成功:返回线程号
创建线程
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
- 该函数第一个参数为 pthread_t 指针,用来保存新建线程的线程号;
- 第二个参数表示了线程的属性,一般传入 NULL 表示默认属性;
- 第三个参数是一个函数指针,就是线程执行的函数。这个函数返回值为 void*,形参为 void*。
- 第四个参数则表示为向线程处理函数传入的参数,若不传入,可用 NULL 填充,
线程的退出与回收
线程主动退出
void pthread_exit(void *retval);
pthread_exit
函数为线程退出函数,在退出时候可以传递一个 void*类型的数据带给主线程,若选择不传出数据,可将参数填充为 NULL。
线程被动退出
int pthread_cancel(pthread_t thread);
其他线程使用该函数让另一个线程退出,该函数传入一个 tid 号,会强制退出该 tid 所指向的线程,若成功执行会返回 0。
线程资源回收(阻塞方式)
int pthread_join(pthread_t thread, void **retval);
该函数为线程回收函数,默认状态为阻塞状态,直到成功回收线程后才返回。第一个参数为要回收线程的 tid
号,第二个参数为线程回收后接受线程传出的数据。
线程资源回收(非阻塞方式)
int pthread_tryjoin_np(pthread_t thread, void **retval);
该函数为非阻塞模式回收函数,通过返回值判断是否回收掉线程,成功回
收则返回 0,其余参数与 pthread_join
一致。
互斥量-锁
初始化互斥量
int pthread_mutex_init(phtread_mutex_t *mutex, const pthread_mutexattr_t *restrict attr);
该函数初始化一个互斥量,第一个参数是改互斥量指针,第二个参数为控制互斥量的属性,一般为 NULL。当函数成功后会返回 0,代表初始化互斥量成功。
使用宏初始化互斥量
pthread_mutex_t mutex = PTHREAD_MUTEX_INITALIZER;
互斥量加锁(阻塞方式)/解锁
int pthread_mutex_lock(pthread_mutex_t *mutex); // 成功:返回 0
int pthread_mutex_unlock(pthread_mutex_t *mutex); // 成功:返回 0
lock 函数与 unlock 函数分别为加锁解锁函数,只需要传入已经初始化好的pthread_mutex_t
互斥量指针。成功后会返回 0。
当某一个线程获得了执行权后,执行 lock
函数,一旦加锁成功后,其余线程遇到 lock 函数时候会发生阻塞,直至获取资源的线程执行 unlock
函数后。unlock
函数会唤醒其他正在等待互斥量的线程。
特别注意的是,当获取 lock 之后,必须在逻辑处理结束后执行 unlock,否则会发生死锁现象!导致其余线程一直处于阻塞状态,无法执行下去。在使用互斥量的时候,尤其要注意使用 pthread_cancel
函数,防止发生死锁现象!
互斥量加锁(非阻塞方式)
int pthread_mutex_trylock(pthread_mutex_t *mutex); //成功返回0
该函数是非阻塞模式通过返回值来判断是否加锁成功,用法与上述阻塞加锁函数一致。
互斥量销毁
int pthread_mutex_destory(pthread_mutex_t *mutex);
该函数是用于销毁互斥量的,传入互斥量的指针,就可以完成互斥量的销毁,成功返回 0。
条件变量
创建条件变量
pthread_cond_t cond = PTHREAD_COND_INITIALIZER; //使用宏快速初始化条件变量
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);//cond_attr 通常为 NULL
销毁条件变量
int pthread_cond_destroy(pthread_cond_t *cond); // 成功返回0
等待条件变量
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
一般结合互斥量进行使用
pthread_mutex_lock(&g_tMutex);
// 如果条件不满足则,会 unlock g_tMutex
// 条件满足后被唤醒,会 lock g_tMutex
pthread_cond_wait(&g_tConVar, &g_tMutex);
/* 操作临界资源 */
pthread_mutex_unlock(&g_tMutex);
通知条件变量
int pthread_cond_signal(pthread_cond_t *cond);
pthread_cond_signal
函数只会唤醒一个等待 cond
条件变量的线程
信号量
定义信号量
#include <semaphore.h> // 头文件
sem_t sem
初始化信号量
int sem_init(sem_t *sem,int pshared,unsigned int value);
- 该函数可以初始化一个信号量,第一个参数传入 sem_t 类型指针;
- 第二个参数传入 0 代表线程控制,否则为进程控制;
- 第三个参数表示信号量的初始值,0 代表阻塞,1 代表运行。
- 待初始化结束信号量后,若执行成功会返回 0。
信号量P/V操作
int sem_wait(sem_t *sem);
int sem_post(sem_t *sem);
sem_wait
函数作用为检测指定信号量是否有资源可用,若无资源可用会阻塞等待,若有资源可用会自动的执行sem-1
的操作。所谓的sem-1
是与上述初始化函数中第三个参数值一致,成功执行会返回 0。sem_post
函数会释放指定信号量的资源,执行sem+1
操作。
通过以上 2 个函数可以完成所谓的 PV 操作,即信号量的申请与释放,完成对线程执行顺序的控制。
信号量等待(非阻塞方式)
int sem_trywait(sem_t *sem); //成功:返回 0
信号量销毁
int sem_destory(sem_t *sem); //成功:返回 0