详解linux多线程——互斥锁、条件变量、读写锁、自旋锁、信号量( 四 )

五、自旋锁(同步)
  自旋锁与互斥量功能一样 , 唯一一点不同的就是互斥量阻塞后休眠让出cpu , 而自旋锁阻塞后不会让出cpu , 会一直忙等待 , 直到得到锁 。
  自旋锁在用户态使用的比较少 , 在内核使用的比较多!自旋锁的使用场景:锁的持有时间比较短 , 或者说小于2次上下文切换的时间 。
  自旋锁在用户态的函数接口和互斥量一样 , 把pthread_mutex_xxx()中mutex换成spin , 如:pthread_spin_init() 。
六、信号量(同步与互斥)
  信号量广泛用于进程或线程间的同步和互斥 , 信号量本质上是一个非负的整数计数器 , 它被用来控制对公共资源的访问 。
  编程时可根据操作信号量值的结果判断是否对公共资源具有访问的权限 , 当信号量值大于 0 时 , 则可以访问 , 否则将阻塞 。PV 原语是对信号量的操作 , 一次 P 操作使信号量减1 , 一次 V 操作使信号量加1 。
#include <semaphore.h>// 初始化信号量int sem_init(sem_t *sem, int pshared, unsigned int value);// 信号量 P 操作(减 1)int sem_wait(sem_t *sem);// 以非阻塞的方式来对信号量进行减 1 操作int sem_trywait(sem_t *sem);// 信号量 V 操作(加 1)int sem_post(sem_t *sem);// 获取信号量的值int sem_getvalue(sem_t *sem, int *sval);// 销毁信号量int sem_destroy(sem_t *sem);【信号量用于同步】:

详解linux多线程——互斥锁、条件变量、读写锁、自旋锁、信号量

文章插图
 
// 信号量用于同步实例#include <stdio.h>#include <unistd.h>#include <pthread.h>#include <semaphore.h> sem_t sem_g,sem_p;//定义两个信号量char ch = 'a'; void *pthread_g(void *arg)//此线程改变字符ch的值{while(1){sem_wait(&sem_g);ch++;sleep(1);sem_post(&sem_p);}} void *pthread_p(void *arg)//此线程打印ch的值{while(1){sem_wait(&sem_p);printf("%c",ch);fflush(stdout);sem_post(&sem_g);}} int main(int argc, char *argv[]){pthread_t tid1,tid2;sem_init(&sem_g, 0, 0); // 初始化信号量为0sem_init(&sem_p, 0, 1); // 初始化信号量为1// 创建两个线程pthread_create(&tid1, NULL, pthread_g, NULL);pthread_create(&tid2, NULL, pthread_p, NULL);// 回收线程pthread_join(tid1, NULL);pthread_join(tid2, NULL);return 0;}【信号量用于互斥】:
详解linux多线程——互斥锁、条件变量、读写锁、自旋锁、信号量

文章插图
 
// 信号量用于互斥实例#include <stdio.h>#include <pthread.h>#include <unistd.h>#include <semaphore.h> sem_t sem; //信号量 void printer(char *str){sem_wait(&sem);//减一 , p操作while(*str) // 输出字符串(如果不用互斥 , 此处可能会被其他线程入侵){putchar(*str);fflush(stdout);str++;sleep(1);}printf("n");sem_post(&sem);//加一 , v操作} void *thread_fun1(void *arg){char *str1 = "hello";printer(str1);} void *thread_fun2(void *arg){char *str2 = "world";printer(str2);} int main(void){pthread_t tid1, tid2;sem_init(&sem, 0, 1); //初始化信号量 , 初始值为 1//创建 2 个线程pthread_create(&tid1, NULL, thread_fun1, NULL);pthread_create(&tid2, NULL, thread_fun2, NULL);//等待线程结束 , 回收其资源pthread_join(tid1, NULL);pthread_join(tid2, NULL);sem_destroy(&sem); //销毁信号量return 0;

【详解linux多线程——互斥锁、条件变量、读写锁、自旋锁、信号量】


推荐阅读