网站作为医院形象建设,网站建设公司首选,工商执照查询官网,标准化建设考评网站文章目录线程的信号量初始化信号量#xff1a;sem_init减少信号量#xff1a;sem_wait增加信号量#xff1a;sem_post删除信号量#xff1a;sem_destroy代码示例线程的互斥量初始化互斥量#xff1a;pthread_mutex_init锁住互斥量#xff1a;pthread_mutex_lock解锁互斥量…
文章目录线程的信号量初始化信号量sem_init减少信号量sem_wait增加信号量sem_post删除信号量sem_destroy代码示例线程的互斥量初始化互斥量pthread_mutex_init锁住互斥量pthread_mutex_lock解锁互斥量pthread_mutex_unlock销毁互斥量pthread_mutex_destroy代码示例线程的信号量
原理简介
线程的信号量和进程的类似维护一个sem_t类型本质是一个int类型的的信号量不同线程通过判断信号量的值来决定是否进行继续运行从而控制线程运行的先后顺序。比如信号量初始化成0线程1调用sem_wait阻塞住等待线程2调用sem_post将限号量增加之后线程1被唤醒从而实现线程1、2执行的顺序。
使用流程
sem_init初始化信号量sem_post增加信号量sem_wait判断并减少信号量
初始化信号量sem_init
sem_init用于初始化信号量的初始值和作用范围。
#include semaphore.h
int sem_init(sem_t *sem, int pshared, unsigned int value);
Link with -pthread;
sem: 需要被初始化的信号量对象;
value: 初始值;
pshared: 10表示信号量线程共享多线程可以共同操作该信号量要求sem变量的作用域能被多个线程访问到2非0表示信号量进程共享多进程可以共同操作该信号量如果是父子进程要求sem变量的作用域能被多个进程访问到若父子进程则可以直接访问若没有关系的进程那么sem要在共享内存中创建;
返回值: 成功返回0失败返回-1并置上errno;减少信号量sem_wait
sem_wait函数判断信号量是否大于0如果大于0则将信号量减一并且立即返回如果小于等于0就阻塞在该函数直到信号量大于0。
#include semaphore.h
int sem_wait(sem_t *sem);
sem: 待操作的信号量;
返回值: 成功返回0失败返回-1并置上errno增加信号量sem_post
sem_post用于给信号量加1
#include semaphore.h
int sem_post(sem_t *sem);
sem: 待操作的信号量;
返回值: 成功返回0失败返回-1并置上errno 删除信号量sem_destroy
#include semaphore.h
int sem_destroy(sem_t *sem);
sem: 待操作的信号量;
返回值: 成功返回0失败返回-1并置上errno代码示例
线程1先被创建但是阻塞在信号量上线程2后被创建被运行后将信号量增加然后线程1识别到信号量大于零才执行后面的步骤。
#include semaphore.h
#include stdio.h
#include pthread.h
#include unistd.hsem_t sem;void * func1(void *arg)
{int ret;ret sem_wait(sem);if (ret ! 0) {perror(sem_wait: );return NULL;}printf(%s: pthread id: %ul\n, __func__, pthread_self());
}void * func2(void *arg)
{int ret;printf(%s: pthread id: %ul\n, __func__, pthread_self());ret sem_post(sem);if (ret ! 0) {perror(sem_post: );return NULL;}
}int
main(int argc, char **argv)
{int ret;pthread_t p1, p2;ret sem_init(sem, 0, 0);if (ret 0) {perror(sem_init: );return -1;}ret pthread_create(p1, NULL, func1, NULL);if (ret ! 0) {perror(pthread_create: );return -1;}sleep(5);ret pthread_create(p2, NULL, func2, NULL);if (ret ! 0) {perror(pthread_create: );return -1;}sleep(1);return 0;}线程的互斥量
原理简介
互斥量底层也是通过锁实现的第一个线程访问互斥量的时候对互斥量加锁后续线程加锁互斥量的时候会被阻塞直到锁被释放互斥量在POSIX中定义互斥量是一种特殊的信号量信号量是一个int数值可以随意大小互斥量只有0和1
使用流程
初始化互斥量锁住互斥量解锁互斥量销毁互斥量
初始化互斥量pthread_mutex_init
互斥量用之前必须初始化
//初始化方法1使用默认属性必须在定义的时候初始化不可以先定义后初始化
pthread_mutex_t mutex PTHREAD_MUTEX_INITIALIZER;
//初始化方法2:
#include pthread.h
int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
mutex: 待初始化的互斥量;
attr: 参数可以直接使用NULL;
返回值: 成功返回0失败返回非0并置上errno锁住互斥量pthread_mutex_lock
#include pthread.h
int pthread_mutex_lock(pthread_mutex_t *mutex);
mutex: 待锁住的互斥量;
返回值: 成功返回0失败返回非0并置上errno解锁互斥量pthread_mutex_unlock
#include pthread.h
int pthread_mutex_unlock(pthread_mutex_t *mutex);
mutex: 待解锁的互斥量;
返回值: 成功返回0失败返回非0并置上errno;销毁互斥量pthread_mutex_destroy
互斥量用完了之后要释放
#include pthread.h
int pthread_mutex_destroy(pthread_mutex_t *mutex);
mutex: 待销毁的互斥量;
返回值: 成功返回0失败返回非0并置上errno;代码示例
#include stdio.h
#include pthread.h
#include unistd.hpthread_mutex_t mutex PTHREAD_MUTEX_INITIALIZER;void * func1(void *arg)
{int ret;ret pthread_mutex_lock(mutex);if (ret ! 0){perror(pthread_mutex_lock: );return NULL;}printf(%s: pthread id: %ul\n, __func__, pthread_self());pthread_mutex_destroy(mutex);
}void * func2(void *arg)
{int ret;printf(%s: pthread id: %ul\n, __func__, pthread_self());
}int
main(int argc, char **argv)
{int ret;pthread_t p1, p2;//ret pthread_mutex_init(mutex, NULL);//if (ret ! 0) {// perror(pthread_mutex_init: );// return -1;//}ret pthread_mutex_lock(mutex);if (ret ! 0){perror(pthread_mutex_lock: );return -1;}ret pthread_create(p1, NULL, func1, NULL);if (ret ! 0) {perror(pthread_create: );return -1;}sleep(5);ret pthread_create(p2, NULL, func2, NULL);if (ret ! 0) {perror(pthread_create: );return -1;}sleep(1);ret pthread_mutex_unlock(mutex);if (ret ! 0){perror(pthread_mutex_lock: );return -1;}sleep(1);return 0;
}