linux下的同步和相互排斥

Linux sync_mutex

看的更舒服点的版本号= =

https://github.com/Svtter/MyBlog/blob/master/Linux/pthread/Linux_producer_consumer.md

Semaphore.h

一份好文档,胜读十年书

本文參考了诸多资料,百度百科。cplusplus等

首先介绍一个头文件

#include <semaphore.h>

这里面包括了大多数的所须要使用的信号量.

包括:

  • int sem_init(sem_t *sem, int pshared, unsigned int value)

    用于初始化信号量。

    value代表信号量的初始值,

    pshare代表信号量是进程内的线程共享。还是进程间共享。

对于Linux而言,就是子进程共享和父进程共享——Linux中不存在线程的问题。Linux中的线程。进程均为进程。仅仅是看进程组。子进程父进程而已。对于进程关系。能够使用pstree查看。

返回0时成功。返回-1时失败。而且设置errno
使用perror输出错误信息:
- EINVAL
value 超过 `SEM_VALUE_MAX`
- ENOSYS
pshared 非零。但系统还没有支持进程共享的信号量。
  • int sem_post(sem_t *sem)

    这个函数相当于V操作,是一个"原子操作"——即是不会被打断(中断)的。

    并行计算中会出现的两个线

    程同一时候对一个变量相加导致变量的值仅产生了一次变化在此处是不成立的。

    返回0时成功,返回-1时失败, 而且设置errno:

    • EINVAL

      sem 不是一个有效的信号量。
    • EOVERFLOW

      信号量同意的最大值将要被超过。

  • int sem_wait(sem_t *sem)

    这个函数相当于P操作,也是一个"原子操作"。

    等待对变量-1,假设不能对变量-1,则进入等待队列

  • int sem_trywait(sem_t *sem)

    假设变量不能-1(即sem_t为0),则不会进入等待队列,直接返回错误代码。
  • int sem_timedwait(sem_t *sem)
  • int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);

    • return 0 (success), return -1 (failure) and set errno:

      • EINTR

        The call was interrupted by a signal handler; see signal(7).

        //调用被信号处理中断
      • EINVAL sem is not a valid semaphore.

          //sem不是有效的信号量

        The following additional error can occur for sem_trywait():

          //以下的错误是sem_trywait()可能发生的:
      • EAGAIN The operation could not be performed without blocking (i.e., the

          semaphore currently has the value zero).

          //除了锁定无法进行别的操作(如信号量当前是0值).

        The following additional errors can occur for sem_timedwait():

          //以下的错误是sem_timedwait()可能发生的:
      • EINVAL The value of abs_timeout.tv_nsecs is less than 0, or greater than or

          equal to 1000 million.

          //abs_timeout.tv_nsecs 的值比0小或者大于等于1000毫秒(译者注:纳秒的值不能比0小,不能比1秒大)
      • ETIMEDOUT

          The call timed out before the semaphore could be locked.

          //在信号量锁定之前就超时了
      • 注意

        对这些函数,信号处理程序总是会中断堵塞,无论是否使用了sigaction(2)的SA_RESTART标志位.
  1. /*=============================================================================
  2. #
  3. # Author: svtter - svtter@qq.com
  4. #
  5. # QQ : 57180160
  6. #
  7. # Last modified: 2014-10-03 20:35
  8. #
  9. # Filename: producer_consumer.cc
  10. #
  11. # Description:
  12. #
  13. =============================================================================*/
  14. #include <cstdio>
  15. #include <unistd.h>
  16. #include <semaphore.h>
  17. #include <pthread.h>
  18. #include <sys/types.h>
  19. #include <stdlib.h>
  20. #include <iostream>
  21. using namespace std;
  22. #define N 5
  23. #define item int
  24. // P/V操作
  25. void P(sem_t* sem)
  26. {
  27. if(sem_wait(sem))
  28. perror("P error!");
  29. }
  30. void V(sem_t* sem)
  31. {
  32. if(sem_post(sem))
  33. perror("V error!");
  34. }
  35. sem_t mutex;
  36. sem_t full;
  37. sem_t empty;
  38. item buffer[N];
  39. int i = 0, j = -1;
  40. void init_sem()
  41. {
  42. sem_init(&mutex, 0, 1);
  43. sem_init(&full, 0, 0);
  44. sem_init(&empty, 0, N);
  45. }
  46. void* producer(void *arg)
  47. {
  48. int product;
  49. while(1)
  50. {
  51. //生成随机数字
  52. product = rand()%100;
  53. // cout << "producer running..." << endl;
  54. P(&empty);
  55. P(&mutex);
  56. buffer[i] = product;
  57. printf("producer produced %d @ %d pos\n",
  58. product, i);
  59. i=(i+1)%N;
  60. V(&mutex);
  61. V(&full);
  62. sleep(1);
  63. }
  64. }
  65. void* consumer(void *arg)
  66. {
  67. int product, temp;
  68. while(1)
  69. {
  70. // cout << "consumer running..." << endl;
  71. P(&full);
  72. P(&mutex);
  73. j = (j+1)%N;
  74. product = buffer[j];
  75. V(&mutex);
  76. V(&empty);
  77. printf("Consumer consumed %d @ %d pos\n",
  78. product, j);
  79. sleep(3);
  80. }
  81. }
  82. int main()
  83. {
  84. //random num
  85. srand(time(NULL));
  86. init_sem();
  87. int error;
  88. pthread_t producer_t, consumer_t;
  89. error = pthread_create(&producer_t, NULL, producer, NULL);
  90. if(error != 0)
  91. printf("error in create producer.\n");
  92. else
  93. printf("create producer success!\n");
  94. pthread_create(&consumer_t, NULL, consumer, NULL);
  95. if(error != 0)
  96. printf("error in create consumer.\n");
  97. else
  98. printf("create consumer success!\n");
  99. pthread_join(producer_t, NULL);
  100. pthread_join(consumer_t, NULL);
  101. return 0;
  102. }

Linux下进程的同步相互排斥实例——生产者消费者的更多相关文章

  1. linux系统编程:线程同步-相互排斥量(mutex)

    线程同步-相互排斥量(mutex) 线程同步 多个线程同一时候訪问共享数据时可能会冲突,于是须要实现线程同步. 一个线程冲突的演示样例 #include <stdio.h> #includ ...

  2. Linux下进程通信的八种方法

    Linux下进程通信的八种方法:管道(pipe),命名管道(FIFO),内存映射(mapped memeory),消息队列(message queue),共享内存(shared memory),信号量 ...

  3. 【网络编程基础】Linux下进程通信方式(共享内存,管道,消息队列,Socket)

    在网络课程中,有讲到Socket编程,对于tcp讲解的环节,为了加深理解,自己写了Linux下进程Socket通信,在学习的过程中,又接触到了其它的几种方式.记录一下. 管道通信(匿名,有名) 管道通 ...

  4. 《linux下进程的创建,执行,监控和终止》

    <linux下进程的创建,执行,监控和终止> http://blog.csdn.net/miss_acha/article/details/43671047 http://blog.csd ...

  5. 【Linux】Linux下进程间的通信方式

    本文内容: 1.进程通信的目的 2.介绍Linux下进程间的4种通信方式:管道,消息队列,共享内存,信号量 ps:套接字也可以用于进程间的通信,不过是不同物理机器上的进程通信,本章讨论是是同一台物理机 ...

  6. linux 下进程通讯详解

    linux 下进程通讯方法主要有以下六种: 1.管道 2.信号 3.共享内存 4.消息队列 5.信号量 6.socket

  7. 【Linux下进程机制】从一道面试题谈linux下fork的运行机制

    今天一位朋友去一个不错的外企面试linux开发职位,面试官出了一个如下的题目: 给出如下C程序,在linux下使用gcc编译: #include "stdio.h" #includ ...

  8. Linux下进程的建立

    Linux下进程的建立 我们都知道,进程就是正在执行的程序.而在Linux中,可以使用一个进程来创建另外一个进程.这样的话,Linux的进程的组织结构其实有点像Linux目录树,是个层次结构的,可以使 ...

  9. Linux下进程间管道通信小作业

    在进行这次作业之前,我们先来看看什么是管道吧! 管道是Linux中很重要的一种通信方式,是把一个程序的输出直接连接到另一个程序的输入,常说的管道多是指无名管道,无名管道只能用于具有亲缘关系的进程之间, ...

随机推荐

  1. POJ 1077 Eight

    题意:经典的八数码=3= 3*3的格子,里面有1~8这8个数字,还有一个空格x,移动空格的位置,直到移到1~8按顺序排好,输出移动的序列. 解法:看到题果断写了个广搜……然后T了……百度了一下说广搜虽 ...

  2. RecordWriter接口解析

    RecordWriter是将Map/Reduce结果(Key-Value)输出到文件系统中. /** * <code>RecordWriter</code> writes th ...

  3. Keep the Customer Satisfied

    题意: n个订单,每个订单有完成需要的天数,和限制的天数,求最多能完成多少订单 分析: 先按限制日期升序排列,若当前订单不能完成,和上面已选中的订单中需要天数中最大的比较,若比它小,则替换他. #in ...

  4. HDU 5768 Lucky7 容斥原理+中国剩余定理(互质)

    分析: 因为满足任意一组pi和ai,即可使一个“幸运数”被“污染”,我们可以想到通过容斥来处理这个问题.当我们选定了一系列pi和ai后,题意转化为求[x,y]中被7整除余0,且被这一系列pi除余ai的 ...

  5. [BILL WEI] A potentially dangerous Request.Path value was detected from the client 异常处理办法

    我们在ASP.net中使用URL导向后, 我们在访问某个地址,或者打开某个系统页面的时候,就会报错误: A potentially dangerous Request.Path value was d ...

  6. linux常用命令之--文本编辑和文本内容查看命令

    linux的文本编辑和文本内容查看命令 1.文本编辑命令 vi:用于编辑文本文件,基本上可以分为三种模式,分别是一般模式.编辑模式.命令行模式. 一般模式:当编辑一个文件时,刚进入文件就是一般模式. ...

  7. PHP 获取文件权限函数

    /* * substr 返回字符串的子串 * base_convert 在任意进制之间转换数字 * fileperms 取得文件的权限 */ // 获取权限 function getChmod($fi ...

  8. 如何给10^7个数据量的磁盘文件排序--bitset

    题目: 输入:给定一个文件,里面最多含有n个不重复的正整数(也就是说可能含有少于n个不重复正整数),且其中每个数都小于等于n,n=10^7.输出:得到按从小到大升序排列的包含所有输入的整数的列表. 分 ...

  9. SeaJS学习笔记(一) ./ 和 ../ 区别

    最近要去实习,公司里使用sea.js进行模块化开发 具体下载安装就不多说了,请参见SeaJS官网 <!DOCTYPE html> <html> <head> < ...

  10. 线性方法用于Binary clssification

    到现在,我们已经学过三种线性方法:linear classification.Linear Regression.logistic Regression.这三种方法的核心都是,不同点在于:最小化的er ...