Linux 信号量同步编程
前一篇文章概述了Linux 系统中信号量互斥编程,这篇文章正好是前一篇的姊妹篇----信号量同步。说它们是姊妹篇是因为它们都是利用了内核的信号量机制实现了进程间的通信。因为两者所解决的问题不同,因此它们使用的场景就会有所区别。
信号量互斥主要解决的问题是:进程间需要同时访问某种资源,但是它们对资源的操作会互相影响对方的操作结果,因此需要一种机制实现让进程在访问资源时能禁止其他进程访问相同的资源。而信号量同步则解决了另一个经典问题:生产者和消费者之间的协同工作问题。
首先描述一下生产者和消费者问题:进程A 负责生产产品(创建并写入文件),进程B 负责消费产品(复制文件),理想的流程是当进程A 创建并写好数据到文件以后,进程B就取走文件。但是两个进程运行时机的不确定往往让这个流程出现混乱,即进程A的生产工作还未完成(如只创建了文件但是没写入数据),进程B 就复制了文件,导致进程B 得到的是一个不完整的文件。事实上问题出现的原因就是两个进程间没有一种同步的机制。
信号量的提出就解决了这个问题。信号量的实现在前一篇文章中有详细介绍,这里只是指出运用信号量同步进程与互斥之间的不同,然后给出一个实例说明。
下面是笔者实现代码的思维导图:

与互斥不同的是,在给信号量赋初值时并不是赋值为1,而是赋值为0,并且在生产者中并没有获取信号量,而在消费者中也没有释放信号量。这样做是为了使两者的运行次序不会影响最后的结果。
可以分析:如果生产者程序先运行,它会依次创建并写入文件,假设此时消费者程序运行,但是此时信号量初值为0,因此消费者程序被挂起。当生产者程序执行完,释放信号量以后,消费者程序继续运行,最后得到正确的文件。
如果消费者程序先运行,它测试到信号量初值是0 ,因此直接被挂起,直到生产者程序运行完才继续运行,可知这样也能够得到正确的文件。
需要注意的是,在上图中的1.7 释放信号量里面,包含一个将初值置为0 的操作,这样是为了在下一次再运行这两个程序时,如果先运行消费者,初值仍然是0。
下面是笔者的测试代码:
生产者代码:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/sem.h> int main(int argc, char **argv)
{
int fd = ;
key_t key;
int semid;
struct sembuf ops;
//创建信号量集合
key = ftok("/home/application/semapthore",);
semid=semget(key,,IPC_CREAT); //将初值置为0
semctl(semid,,SETVAL,); //创建文件
fd = open("./product.txt",O_RDWR|O_CREAT,); //休息
sleep(); //写入数据
write(fd,"Product is finished!",); //关闭文件
close(fd); //释放信号量
ops.sem_num=;
ops.sem_op=;
ops.sem_flg = SEM_UNDO;
semop(semid,&ops,);
semctl(semid,,SETVAL,);
return ;
}
消费者代码;
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h> int main(int argc,char **argv)
{ key_t key;
int semid;
struct sembuf ops;
//打开信号量集合
key = ftok("/home/application/semapthore",);
semid=semget(key,,IPC_CREAT);
//获取信号量
ops.sem_num = ;
ops.sem_op = -;
ops.sem_flg = SEM_UNDO;
semop(semid,&ops,); //消费文件
system("cp ./product.txt ./comsum/"); return ;
}
Linux 信号量同步编程的更多相关文章
- Linux信号量同步共享内存实验.
Linux信号量同步共享内存实验. Linux信号量同步共享内存实验. 简述 程序流程 信号量和共享内存的系统函数 信号量系统函数及接口 共享内存系统函数及接口 写程序 读程序 简述 本文主要内容是自 ...
- Linux 信号量互斥编程
所谓信号量,其实就是一个数字.内核给这个数字赋予一定的含义,让它等于不同的值时所表示的意义不同.这样就可以用它来标示某种资源是否正被使用.信号的分类其实挺多的,主要还是二值和计数器.这里讨论二值 现在 ...
- 转载自~浮云比翼:Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)
Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥) 介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可 ...
- linux信号量之进程间同步
概念 linux信号量: 允许多个线程同时进入临界区,可以用于进程间的同步. 和互斥锁(mutex)的区别: 互斥锁只允许一个线程进入临界区. 所在头文件: semaphore.h 主要函数 初始化函 ...
- Linux多线程--使用信号量同步线程【转】
本文转载自:http://blog.csdn.net/ljianhui/article/details/10813469 信号量.同步这些名词在进程间通信时就已经说过,在这里它们的意思是相同的,只不过 ...
- Linux线程的信号量同步
信号量和互斥锁(mutex)的区别:互斥锁只允许一个线程进入临界区,而信号量允许多个线程同时进入临界区. 不多做解释,要使用信号量同步,需要包含头文件semaphore.h. 主要用到的函数: int ...
- 【linux草鞋应用编程系列】_3_ 进程间通信
一.进程间通信 linux下面提供了多种进程间通信的方法, 管道.信号.信号量.消息队列.共享内存.套接字等.下面我们分别 介绍管道.信号量.消息队列.共享内存. 信号和套 ...
- Linux内核同步机制
http://blog.csdn.net/bullbat/article/details/7376424 Linux内核同步控制方法有很多,信号量.锁.原子量.RCU等等,不同的实现方法应用于不同的环 ...
- Linux下的编程实战【转】
一篇比较不错的文章, 降到了 makefile make , gcc编译器,GDB调试器, Linux文件系统,Linux文件API,.C语言库函数(C库函数的文件操作实际上是独立于具体的操作系统平台 ...
随机推荐
- Stand-up meeting
A stand-up meeting (or simply "stand-up") is a daily team-meeting held to provide a status ...
- Android游戏与应用开发最佳学习路线图
Android 游戏与应用开发最佳学习路线图 为了帮助大家更好的学习 Android,并快速入门特此我们为大家制定了以下学习路线图,希望能够帮助大家. 一.路线图概括: 二.具体需要掌握知识点: 三. ...
- 近5年133个Java面试问题列表
Java 面试随着时间的改变而改变.在过去的日子里,当你知道 String 和 StringBuilder 的区别就能让你直接进入第二轮面试,但是现在问题变得越来越高级,面试官问的问题也更深入. 在我 ...
- Shell函数:Shell函数返回值、删除函数、在终端调用函数
函数可以让我们将一个复杂功能划分成若干模块,让程序结构更加清晰,代码重复利用率更高.像其他编程语言一样,Shell 也支持函数.Shell 函数必须先定义后使用. Shell 函数的定义格式如下: f ...
- 捕获 PHP 致命错误 Fatal Errors
register_shutdown_function()函数都将会你的程序执行完后执行,无论你的程是否运行正常. 所以,在这个函数前执行任何操作我们都要检查是否真的有致命错误出现.如果出现致命错误,我 ...
- Jquery- 错误消息"Date"未定义,"String"未定义
在jquery的高版本(1.7-1.9)提示“String”未定义,稍低版本提示“Date”未定义错误 解决办法: 1.找到你发生错误的代码(即执行那条代码时发生的错误) 2.使用setTimeout ...
- [置顶] 第二届微软CRM交流年会
第二届微软CRM交流会将在12月14日举行,亲们要是感兴趣可以查看下面的活动详情.Jeff也是第一次参加这类活动,作为本次活动的嘉宾我为大家带来一个挺有意思的分享主题<Dynamics CRM ...
- 修改Unity脚本模板的方法合计
作为一个习惯于偷懒的程序,重复性的无聊内容是最让人无奈的事,就比如我们创建Unity脚本之后,需要手动调整生成的新脚本的格式.编码.内容:如果我们要编写的是编辑器或者服务器端脚本,需要修改的内容就会更 ...
- BSEG和BSIS、BSAS、BSID、BSAD、BSIK、BSAK六个表的关系(转)
BSEG和BSIS.BSAS.BSID.BSAD.BSIK.BSAK 六个表的关系 1.数据关系: BSAS+BSIS+BSAK+BSIK+BSAD+BSID = BSEG 2.六个表说明: clea ...
- WEB DYNPRO SAP HELP
http://help.sap.com/saphelp_nw70ehp1/helpdata/EN/43/70d83e8cb23d67e10000000a114084/content.htm