多线程、信号量函数

线程:目的→使多个任务并行处理

#include<pthread.h>
创建线程
int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
thread:用于引用新创建的线程,指向新创建线程的id;
attr:进程属性,一般不需要特殊配置,可简单配置为NULL;
start_routine:传递新线程所要执行的函数地址;
arg:传递新线程执行函数的参数
返回值:成功,返回0

获得线程ID(线程标识)
1)    线程ID在pthread_create调用时会回返给其调用者;
2)    线程可以调用pthread_t pthread_self(void)获得自己的ID

线程退出三种方式:
1)    执行完成后隐式退出;
2)    由线程本身调用pthread_exit(void *retval)函数退出;
3)    由其它线程调用ptherad_cance(pthread_t pthread)函数退出

pthread_t 用于声明线程ID

线程等待
Int pthread_join(pthread_t tid, void **status)
功能:阻塞调用线程,直到指定线程终止
Tid:等待退出线程的ID
status:线程退出的返回值指针,指向返回值的指针

线程清除
从pthread_cleanup_push的调用点到pthread_cleanup_pop之间的程序段中的终止动作(包括调用pthread_exit()和异常终止,但不包括return)都将执行pthread_cleanup_push()所指定的清理函数。
void pthread_cleanup_push(void(*rtn)(void *), void *arg)
功能:将清除函数压入清除栈,等待异常退出时执行
Rtn:清除函数
Arg:清除函数参数
void pthread_cleanup_pop(int execute)
功能:将清除函数弹出清除栈(后进先出)
参数:execute执行到pthread_cleanup_pop()时是否在弹出清理函数的同时执行该函数,非0:执行;0:不执行

Pthread_cond_signal()函数作用:发送一个信号给另一个正处于阻塞等待状态的线程,使其脱离阻塞状态而继续执行;

pthread_t pthread_self(void)
功能:返回新创建线程的id

rm –rf !(*.c)   //删除除了你.c文件以外的所有文件

pthread线程函数:
pthread_create():创建一个线程
pthread_exit():退出一个线程
pthread_join():阻塞当前线程,直到另一个线程执行结束
pthread_attr_init():设置线程是否脱离属性
pthread_kill():给线程发kill信号

线程同步函数:
pthread_mutex_lock():互斥加锁
pthread_mutex_unlock():互斥锁解锁
pthread_cond_init():初始化条件变量
pthread_cond_signal():发送信号唤醒进程
pthread_cond_wait():等待条件变量的特殊事件发生

线程互斥
互斥锁初始化的两种方式:

1)    静态初始化:
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
2)    动态初始化
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);
//int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)

 多线程对临界资源的访问,同一时刻只能一个线程访问,每个线程需要加锁
int pthread_mutex_lock(pthread_mutex_t *mptr);    //线程加锁
int pthread_mutex_trylock(pthread_mutex_t *mptr)     //线程试加锁

int pthread_mutex_unlock(pthread_mutex_t *mptr)   //线程解锁
使用互斥锁之前需要先定义pthread_mutex_t *类型变量
互斥锁属性
1)    互斥锁属性初始化:
pthread_mutexattr_init(pthread_mutexattr_t *mattr)
2)    设置与获取互斥锁范围:
可以指定是该进程内不同线程间同步还是该进程与其他进程同步
pthread_mutexattr_setpshared(pthread_mutexattr_t *mattr, int pshared)
pthread_mutexattr_getshared(pthread_mutexatttr_t *mattr, int *pshared)

互斥锁范围可设置两种:
PTHREAD_PROCESS_SHARE、PTHREAD_PROCESS_PRIVATE,默认是后者,表示进程内使用锁;
3)    设置与获取互斥锁类型
pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
pthread_mutexattr_gettype(pthread_mutexattr_t *attr, int *type)

互斥锁类型取值:
PTHREAD_MUTEX_TIMED_NP 普通锁,缺省值
PTHREAD_MUTEX_RECURSIVE_NP 嵌套锁
PTHREAD_MUTEX_ERRORCHEAK_NP 检错锁
PTHREAD_MUTEX_ADAPTIVE_NP 适应锁

线程取消
    pthread_cancel调用并不等待线程终止,它只是提出请求;线程在取消请求(pthread_cancel)发出后会继续运行,直到到达某个取消点;取消点是线程检查是否被取消并按照请求进行动作的一个位置。
int pthread_cancel(pthread_t pthread)
发送终止信号给thread线程,若成功则返回0;发送成功并不意味着thread会终止。
int pthread_setcancelstate(int state, int *oldstate)
设置本线程对cancel的反应,state有两种取值:PTHREAD_CANCEL_ENABLE、PTHREAD_CANCEL_DISABLE,分别表示收到信号后为cancel状态和忽略cancel信号继续运行。
int pthread_setcanceltype(int type, int *oldtype)
设置本线程取消动作的执行时机,type有两种值:PTHREAD_CANCEL_DEFFERED、PTHREAD_CANCEL_ASYCHRONOUS,仅当cancel状态为enable时有效,分别表示收到信号后继续运行至下一个取消点再退出和立即执行取消动作退出。

线程存储(线程私有数据)
表面上看起来是一个全局变量,所有线程都可以使用它,而它的值在每个线程中又是单独存储的。
1)    创建一个pthread_key_t类型的变量
           pthread_key_t key
2)    调用pthread_key_create()函数创建该变量
           int pthread_key_create(pthread_key_t *key, void(*destructor)(void *))
第一个参数为上面创建的变量;第二个参数是一个清理函数,在线程释放该线程存储时被调用。
3)    调用int pthread_setspecific(pthread_key_t key, const void *value)
第一个参数为上面创建的变量;第二个参数是存储值。
4)    调用void *pthread_getspecific(pthread_key_t key),取出存储的值。
5)    调用pthread_key_delete(pthread_key_t key),释放线程存储空间。


线程同步
int pthread_cond_wait(pthread_cond_t *cptr, pthread_mutex_t *mptr);
int pthread_cond_signal(pthread_cond_t *cptr);
参数cptr:指向条件变量
条件变量始终与互斥锁一起使用;对条件变量的测试是在互斥锁的保护下进行的。
pthread_cond_t cond=PTHREAD_COND_INITIALIZER  //条件变量初始化
条件变量cond是始终与互斥锁mutex一起使用
信号量函数
int sem_init(sem_t *sem, int pshared, unsigned int value)
功能:创建一个信号量,并初始化它的值;
参数sem:信号量
参数pshared:决定信号量能否在几个进程间共享(一般不共享,取值为0);
参数value:信号量初始化值

int sem_wait(sem_t *sem)    //将信号量的值减一;sem<0时,会阻塞进程;
int sem_trywait(sem_t *sem)   //将信号量的值减一;sem<0时,会立即返回;
执行sem_wait和sem_trywait,sem减一
int sem_post(sem_t *sem)     //sem值加一,同时发出信号唤醒进程
执行sem_post,sem加一
int sem_getvalue(sem_t *sem)     //获得信号量的值
int sem_destory(sem_t *sem)      //删除信号量
信号量sem >= 0,表示该线程(或进程)具有公共资源访问权;
信号量sem < 0,表示该线程(或进程)不具有公共资源访问权
一般初始化两个信号量,一个为1,一个为0.
信号量可以控制多线程的执行顺序

猜你喜欢

转载自blog.csdn.net/daha1314/article/details/84589329