1.POSIX信号量

1.有名信号量

#include <fcntl.h>           /* For O_* constants */
#include <sys/stat.h>        /* For mode constants */
#include <semaphore.h>
sem_t *sem_open(const char *name, int oflag);
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
int sem_close(sem_t *sem);
int sem_unlink(const char *name);

2.匿名信号量

#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_destroy(sem_t *sem);

(1)匿名信号量只存在于内存中, 并要求使用信号量的进程必须可以访问内存; 这意味着他们只能应用在同一进程中的线程, 或者不同进程中已经映射相同内存内容到它们的地址空间中的线程.

(2)匿名信号量必须用sem_init 初始化,sem_init 函数的第二个参数pshared决定了线程共享(pshared=0)还是进程共享(pshared!=0),也可以用sem_post 和sem_wait 进行操作,在共享内存释放前,匿名信号量要先用sem_destroy 销毁

3.PV操作

int sem_wait(sem_t *sem);    //P操作
int sem_post(sem_t *sem);    //V操作

(1) wait操作实现对信号量的减1, 如果信号量计数原先为0则会发生阻塞;

(2)post操作将信号量加1, 在调用sem_post时, 如果在调用sem_wait中发生了进程阻塞, 那么进程会被唤醒并且sem_post增1的信号量计数会再次被sem_wait减1;

2.POSIX互斥锁

#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *mutex,
                       const pthread_mutexattr_t *mutexattr);        //互斥锁初始化, 注意:函数成功执行后,互斥锁被初始化为未锁住状态。
int pthread_mutex_lock(pthread_mutex_t *mutex);    //互斥锁上锁
int pthread_mutex_trylock(pthread_mutex_t *mutex);    //互斥锁判断上锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);    //互斥锁解锁
int pthread_mutex_destroy(pthread_mutex_t *mutex);    //消除互斥锁

3.生产者和消费者问题

#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <pthread.h>
#include <semaphore.h>#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>#define ERR_EXIT(m) \do \{ \perror(m); \exit(EXIT_FAILURE); \}while(0)#define CONSUMERS_COUNT 1
#define PRODUCERS_COUNT 5
#define BUFFSIZE 10int g_buffer[BUFFSIZE];unsigned short in = 0;
unsigned short out = 0;
unsigned short produce_id = 0;
unsigned short consume_id = 0;sem_t g_sem_full;
sem_t g_sem_empty;
pthread_mutex_t g_mutex;pthread_t g_thread[CONSUMERS_COUNT + PRODUCERS_COUNT];void* consume(void* arg) {int i;int num = *(int*)arg;free(arg);while(1) {printf("%d wait buffer not empty\n", num);sem_wait(&g_sem_empty);pthread_mutex_lock(&g_mutex);for(i=0; i<BUFFSIZE; i++) {printf("%02d ", i);if(g_buffer[i] == -1) printf("%s", "null");elseprintf("%d", g_buffer[i]);        if(i==out) printf("\t<--consume");printf("\n");            }consume_id = g_buffer[out];printf("%d begin consume product %d\n", num, consume_id);g_buffer[out] = -1;out = (out+1) % BUFFSIZE;printf("%d end consume product %d\n", num, consume_id);pthread_mutex_unlock(&g_mutex);sem_post(&g_sem_full);sleep(5);}return NULL;
}void* produce(void* arg) {int i;int num = *(int*)arg;free(arg);while(1) {printf("%d wait buffer not full\n", num);sem_wait(&g_sem_full);pthread_mutex_lock(&g_mutex);for(i=0; i<BUFFSIZE; i++) {printf("%02d ", i);if(g_buffer[i] == -1) printf("%s", "null");elseprintf("%d", g_buffer[i]);        if(i==in) printf("\t<--produce");printf("\n");         }printf("%d begin produce product %d\n", num, produce_id);g_buffer[in] =     produce_id;in = (in+1) % BUFFSIZE;printf("%d end produce product %d\n", num, produce_id++);pthread_mutex_unlock(&g_mutex);sem_post(&g_sem_empty);sleep(1);}return NULL;
}
int main(int argc, char* argv[]) {int i;for(i=0; i<BUFFSIZE; i++) {g_buffer[i] = -1;}//sem_init(第二个参数不为0,表示可用于不同进程间的线程通信,可以将信号放到共享内存中sem_init(&g_sem_full, 0, BUFFSIZE);sem_init(&g_sem_empty, 0, 0);pthread_mutex_init(&g_mutex, NULL); for(i=0; i<CONSUMERS_COUNT; i++) {int* p = (int*)malloc(sizeof(int));*p = i;pthread_create(&g_thread[i], NULL, consume, (void*)p); }for(i=0; i<PRODUCERS_COUNT; i++) {int* p = (int*)malloc(sizeof(int));*p = i;pthread_create(&g_thread[CONSUMERS_COUNT+i], NULL, produce, (void*)p); }for(i=0; i<CONSUMERS_COUNT+PRODUCERS_COUNT; i++) {pthread_join(g_thread[i], NULL);}
//  sem_destory(&g_sem_full);
//  sem_destory(&g_sem_empty);
//  pthread_mutex_destory(&g_mutex);return 0;
}

4.自旋锁

int pthread_spin_destroy(pthread_spinlock_t *lock);
int pthread_spin_init(pthread_spinlock_t *lock, int pshared);

int pthread_spin_lock(pthread_spinlock_t *lock);
int pthread_spin_trylock(pthread_spinlock_t *lock);

int pthread_spin_unlock(pthread_spinlock_t *lock);

(1)自旋锁类似于互斥锁, 它的性能比互斥锁更高;

(2)自旋锁与互斥锁很重要的一个区别在于: 线程在申请自旋锁的时候, 线程并不会挂起, 它总是处于忙等待的状态(一直在自旋, CPU处于空耗的状态);

(3)自旋锁可用于以下情况:锁被持有的时间短, 而且线程并不希望在重新调度上花费太多的成本.

(4)自旋锁通常作为底层原语用于实现其他类型的锁: 比如有些互斥锁的实现在试图获取互斥量的时候会自旋一小段时间, 只有在自旋计数到达某一阈值的时候才会休眠; 因此, 很多互斥量的实现非常搞笑, 以至于应用程序采用互斥锁的性能与曾经采用过自旋锁的性能基本上是相同的.

(5)因此, 自旋锁只在某些特定的情况下有用, 比如在用户层, 自旋锁并不是非常有用, 除非运行在不允许抢占的实时调度类中.

5.读写锁

int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,
                        const pthread_rwlockattr_t *restrict attr);
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

(1)读写锁与互斥量类似, 不过读写锁允许更高的并行性. 读写锁用于读称为共享锁, 读写锁用于写称为排它锁;

(2)只要没有线程持有给定的读写锁用于写, 那么任意数目的线程可以持有读写锁用于读;

(3)仅当没有线程持有某个给定的读写锁用于读或用于写时, 才能分配读写锁用于写;

POSIX 信号量和互斥锁相关推荐

  1. c++ linux 线程等待与唤醒_C++ Linux线程同步机制:POSIX信号量,互斥锁,条件变量...

    线程同步机制:POSIX 信号量,互斥量,条件变量 POSIX 信号量 常用的POSIX 信号量函数为如下5个: sem_init sem_destroy sem_wait sem_trywait s ...

  2. linux网络编程-posix信号量与互斥锁(39)

    -posix信号量信号量 是打开一个有名的信号量 sem_init是打开一个无名的信号量,无名信号量的销毁用sem_destroy sem_wait和sem_post是对信号量进行pv操作,既可以使用 ...

  3. linux网络编程之posix 线程(三):posix 匿名信号量与互斥锁 示例生产者--消费者问题

    http://blog.csdn.net/jnu_simba/article/details/9123603 一.posix 信号量 信号量的概念参见这里.前面也讲过system v 信号量,现在来说 ...

  4. Linux多线程的同步-----信号量和互斥锁

    前面两篇给基本概念讲过了,大家有兴趣的可以去看一下: Linux多线程_神厨小福贵!的博客-CSDN博客进程和线程的区别有哪些呢?进程是资源分配的最小单位,线程是CPU调度的最小单位进程有自己的独立地 ...

  5. 210224阶段三信号量、互斥锁

    目录 一.学习的知识点 进程 线程 进程和线程 信号量和互斥锁 应用场景 二.上课没有听懂或者没有理解的地方 三.当天学习的收获 一.学习的知识点 ls -a 显示隐藏文件 cd ~ 回到home目录 ...

  6. 两个精彩的比喻:吞吐量和延迟、信号量和互斥锁

    本文为转载文章,觉得很有意思,原文在这里. 我们知道,计算机中有很多概念并不容易理解,有些时候一个好的比喻能胜过很多句解释.下面两个是我看到的两个很精彩的比喻,拿出来和大家分享一下. 第一比喻是关于吞 ...

  7. 进程、线程、信号量和互斥锁

    进程.线程.信号量和互斥锁 本文转自博客<进程与线程的一个简单解释> 计算机的核心是CPU,它承担了所有的计算任务.它就像一座工厂,时刻在运行. 假定工厂的电力有限,一次只能供给一个车间使 ...

  8. Linux内核中的同步原语:自旋锁,信号量,互斥锁,读写信号量,顺序锁

    Linux内核中的同步原语 自旋锁,信号量,互斥锁,读写信号量,顺序锁 rtoax 2021年3月 在英文原文基础上,针对中文译文增加5.10.13内核源码相关内容. 1. Linux 内核中的同步原 ...

  9. 信号量和互斥锁的区别

    一:信号量与互斥锁之间的区别: 互斥量用于线程的互斥,信号线用于线程的同步.这是互斥量和信号量的根本区别,也就是互斥和同步之间的区别. 互斥量值只能为0/1,信号量值可以为非负整数. 也就是说,一个互 ...

最新文章

  1. 设计模式 — 创建型模式 — 建造者模式
  2. MySQL使用用户变量需确定取值的顺序
  3. java8 stream案例分析
  4. 华为机试——数字颠倒
  5. python 生成器函数_Python 生成器函数
  6. 【程序猿脱单指南】送你一份大礼包去追女神
  7. DataBseDesign工作笔记003---ERStudio使用笔记_基本使用方法详解
  8. Python实战技术 - Python虚拟隔离环境 和 Docker技术
  9. idea报错:Invalid bound statement (not found)
  10. python模拟gps定位_python 模拟 GPS, $GPRMC $GPRMC
  11. 计算机组成原理 精选习题集
  12. chromedriver与chrome各版本及下载地址
  13. 抖音:技术优化打造最佳创作体验
  14. 双硬盘双win10互不干扰_笔者详解win10系统双硬盘经常提示“盘符交错”的技巧...
  15. 【隐私计算笔谈】MPC系列专题(五):Beaver三元组和BMR协议
  16. JavaScript高级教程(25)——ES6
  17. 数月沉淀终圆梦,西安校区刘同学转行测试收获12K,嫽扎咧
  18. 数据库间表结构对比和数据对比
  19. HTTP协议中URI和URL有什么区别
  20. java for 一秒钟可以循环多少次

热门文章

  1. CSS学习总结3:CSS定位
  2. Parasoft C++test使用教程:执行测试用例(上)
  3. nginx中给目录增加密码保护实现程序
  4. 配置 MAC地址表实现绑定和过滤
  5. 中国移动总经理易人对产业格局的影响
  6. 一句公道话引发的......
  7. 用VMware GSX和W2K群集服务实现Exchange群集
  8. Linux 命令(23)—— rm 命令
  9. Web 前端开发初学者十问集锦(2)
  10. python 调用apollo