-posix信号量信号量

是打开一个有名的信号量

sem_init是打开一个无名的信号量,无名信号量的销毁用sem_destroy

sem_wait和sem_post是对信号量进行pv操作,既可以使用在有名的信号量也可以使用在无名的信号量

无名信号量是否意味着它不能够用于不同进程的多个线程之间的通信了

如果sem_init是非零的参数,那么这个无名的信号量可以用于不同进程间的多个线程之间的通信,前提条件是这个信号量的对象必须存储在共享内存区才可以。

上面这是互斥锁是无名的互斥锁,同样也可以可以用于不同进程间的多个线程之间的通信,前提条件是这个信号量的对象必须存储在共享内存区才可以。

下面我们使用互斥锁来解决生产者消费者的问题

生产者消费者问题是这样描述的,有一个缓冲区,是一个有大小的缓冲区,对于生产者来说,首先判断当前缓冲区是否满了,满了就阻塞不再生产,我们使用信号量来实现

使用信号量p(sem_full)的信号量来实现,初始化的值就是缓冲区的大小,一旦生产了一个产品sem_full的计数值值减一,一旦我们生成了产品,缓冲区不再是空的状态,我们使用一个

v(sem_empty)的信号量,用来告诉消费者可以来消费产品了,我们在生成产品的时候,由于生产者可能是多个,我们需要有一个互斥锁来包含缓冲区。

对于消费者,消费者也存在多个,首先判断当前缓冲区是否是空的,如果是空的就不能消费产品,需要等待生产者给消费者一个信号,消费者新建一个p(sem_empty)信号,使得信号量加一,这样消费者就可以消费产品了,

一旦消费者消费了一个产品,就会使得缓冲区的大小加一v(sem_full)这样的信号量,对于缓冲区,多个消费者也需要互斥

对于初始化,一开始只能生产产品,不能消费产品,假设缓冲区的大小是10,sem_full是10,sem_empty为0

下面我们通过代码来理解下面的问题:

信号量是在多线程环境中共享资源的计数器

sem_wait() 减小(锁定)由sem指定的信号量的值.如果信号量的值比0大,
  那么进行减一的操作,函数立即返回.
  如果信号量当前为0值,那么调用就会一直阻塞直到或者是信号量变得可以进行减一的操作
  (例如,信号量的值比0大),或者是信号处理程序中断调用

当前初始化的sem_full的值是10,减一之后函数会立即返回不会阻塞

sem_wait   sem_post

信号量的数据类型为结构sem_t,它本质上是一个长整型的数。函数sem_init()用来初始化一个信号量。它的原型为:  

extern int sem_init __P ((sem_t *__sem, int __pshared, unsigned int __value));  

sem为指向信号量结构的一个指针;pshared不为0时此信号量在进程间共享,否则只能为当前进程的所有线程共享;value给出了信号量的初始值。  

函数sem_post( sem_t *sem )用来增加信号量的值。当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不在阻塞,选择机制同样是由线程的调度策略决定的。  

函数sem_wait( sem_t *sem )被用来阻塞当前线程直到信号量sem的值大于0,解除阻塞后将sem的值减一,表明公共资源经使用后减少。函数sem_trywait ( sem_t *sem )是函数sem_wait()的非阻塞版本,它直接将信号量sem的值减一。  

函数sem_destroy(sem_t *sem)用来释放信号量sem。 

信号量用sem_init函数创建的,下面是它的说明:
  #include<semaphore.h>
 int sem_init (sem_t *sem, int pshared, unsigned int value);

生产完一个产品之后sem_post(&sem_empty)是的sem_empty的信号量的值加一

我们来看程序的代码:

#include <unistd.h>
#include <sys/types.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 1
#define BUFFSIZE 10

int 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;
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");
else
printf("%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(1);
}
return NULL;
}

void *produce(void *arg)
{
int num = (int)arg;
int i;
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");
else
printf("%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(5);
}
return NULL;
}

int main(void)
{
int i;
for (i = 0; i < BUFFSIZE; i++)
g_buffer[i] = -1;

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++)
pthread_create(&g_thread[i], NULL, consume, (void *)i);

for (i = 0; i < PRODUCERS_COUNT; i++)
pthread_create(&g_thread[CONSUMERS_COUNT + i], NULL, produce, (void *)i);

for (i = 0; i < CONSUMERS_COUNT + PRODUCERS_COUNT; i++)
pthread_join(g_thread[i], NULL);

sem_destroy(&g_sem_full);
sem_destroy(&g_sem_empty);
pthread_mutex_destroy(&g_mutex);

return 0;
}

编译的时候需要加上gcc proudct.c -o product -lpthread

可以查看博客:

http://blog.csdn.net/nk_test/article/details/50449704

转载于:https://www.cnblogs.com/kebibuluan/p/7110711.html

linux网络编程-posix信号量与互斥锁(39)相关推荐

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

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

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

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

  3. POSIX 信号量和互斥锁

    1.POSIX信号量 1.有名信号量 #include <fcntl.h>           /* For O_* constants */ #include <sys/stat. ...

  4. Linux系统编程:使用mutex互斥锁和条件变量实现多个生成者和消费者模型

    实现代码 如题,使用mutex互斥锁和条件变量实现多个生成者和消费者模型. 直接上代码,需要线程中的互斥锁和条件变量的相关知识进行支撑.这里就不细说了呀,代码中有一定的注释. #include < ...

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

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

  6. Linux信号量与互斥锁解决生产者与消费者问题

    先来看什么是生产者消费者问题: 生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问 ...

  7. 漫画Linux 并发、竞态、互斥锁、自旋锁、信号量

    1. 锁的由来? 学习linux的时候,肯定会遇到各种和锁相关的知识,有时候自己学好了一点,感觉半桶水的自己已经可以华山论剑了,又突然冒出一个新的知识点,我看到新知识点的时候,有时间也是一脸的懵逼,在 ...

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

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

  9. C++教程网之Linux网络编程视频 Unix网络编程视频

    教程非常不错,价值280元,绝对是干货 Linux网络编程(总共41集) 讲解Linux网络编程知识,分以下四个篇章. Linux网络编程之TCP/IP基础篇 Linux网络编程之socket编程篇 ...

最新文章

  1. Struts2笔记——struts常用标签
  2. 蓝桥杯 基础练习 芯片测试
  3. 蓝桥杯2017年第八届C/C++省赛C组第一题-贪吃蛇长度
  4. Cglib 如何实现多重代理?
  5. 向博客园提交了MVP申请
  6. C语言例题——简易秒表
  7. 《数据结构》-二叉树(二叉链表实现)
  8. Datawhale学习记录 动手学数据分析(以Kaggle泰坦尼克号为案例)——Task01数据加载及探索性数据分析
  9. 前端学习笔记 - promise是什么?能解决什么问题?
  10. 中国的开源之夏来了!
  11. minigui 3.2.0:基于miniStudio应用TrueType字体的过程(1)
  12. Chrome Extension ContextMenus 创建 适配Manifest3
  13. netstat -ano | findstr 8611查看到大量的TIME_WAIT状态的解决办法
  14. ubuntu安装python3.6_Ubuntu 16.04上安装和使用Python3.6
  15. matlab 时间戳转换
  16. PC 机与单片机通信(RS232 协议)
  17. 民宿逐渐兴起后 旅游会不会是90后创业新方向?
  18. 基于5G+MEC的电站行业专网部署方案研究
  19. Integer. valueOf()的使用
  20. 计算机辅助设计i ps,计算机辅助设计I(PS)

热门文章

  1. SAP S4HANA 使用BP创建供应商报错 - You cannot create a vendor with grouping G001 - 对策
  2. SAP S4HANA 账户组的配置里'Int.Std.Grping'选项没勾选导致ABAP程序报错
  3. 对时间序列分类的LSTM全卷积网络的见解
  4. 干货丨浅析分布式系统(经典长文,值得收藏)
  5. 业界丨2018年人工智能和机器学习路在何方? 看看美国公司准备怎么做
  6. 有序回归(ordinal regression)
  7. 欢迎参加2022年第一次《城市大脑建设标准规范》专家研讨会
  8. 理解与理论:人工智能基础问题的悲观与乐观
  9. MIT对话马斯克:关于自动驾驶、爱和未来世界|厚势汽车
  10. 物联网面临的7大网络安全威胁