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 = 0;
    key_t key;
    int semid;
    struct sembuf ops;
    //创建信号量集合
    key = ftok("/home/application/semapthore",1);
    semid=semget(key,1,IPC_CREAT);

    //将初值置为0
    semctl(semid,0,SETVAL,0);

    //创建文件
    fd = open("./product.txt",O_RDWR|O_CREAT,0755);

    //休息
    sleep(20);

    //写入数据
    write(fd,"Product is finished!",21);

    //关闭文件
    close(fd);

    //释放信号量
    ops.sem_num=0;
    ops.sem_op=1;
    ops.sem_flg = SEM_UNDO;
    semop(semid,&ops,1);
    semctl(semid,0,SETVAL,0);
    return 0;
}

消费者代码;

#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",1);
    semid=semget(key,1,IPC_CREAT);
    //获取信号量
    ops.sem_num = 0;
    ops.sem_op = -1;
    ops.sem_flg = SEM_UNDO;
    semop(semid,&ops,1);

    //消费文件
    system("cp ./product.txt ./comsum/");

    return 0;
}

时间: 2024-10-07 05:25:53

Linux 信号量同步编程的相关文章

第三季-第17课-信号量同步编程

第17课-信号量同步编程 17.1 核心概念--进程同步 一组并发进程进行互相合作.互相等待,使得各进程按一定的顺序执行的过程称为进程间的同步. 17.2 生产者消费者问题 1. 问题描述 这里面有两个角色:生产者和消费者.假设生产者生产的产品需要两步才能完成并且使用.但是,当生产者刚刚完成了对产品的第一步加工的时候,产品就被消费者买走了.可是他们之间并没有相应的沟通,这就导致,消费者会以为他买到了完成的产品. 2. 程序化 在文件夹里面创建producer.c和customer.c文件,同时创

Linux 信号量互斥编程

所谓信号量,其实就是一个数字.内核给这个数字赋予一定的含义,让它等于不同的值时所表示的意义不同.这样就可以用它来标示某种资源是否正被使用.信号的分类其实挺多的,主要还是二值和计数器.这里讨论二值 现在有个文件,有两个进程要同时访问它.进程A 要往里面写入 "Math class is cancel",进程B 要往里面写入“English test”.正常情况下这两个信息会被完整的写入文件中.但是如果进程A写到"Math class" 就暂停,接着B进程就开始写“En

信号量同步编程

信号量同步 一.核心概念 进程同步核心概念:一组并发进程进行互相合作,互相等待,使得各进程按一定的顺序执行的过程 称为进程间的同步. 二.生产力消费问题 (1)问题描述   (2)问题程序化    #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/ipc.h> #include <sys/sem.

第15课-信号量同步编程

1.进程同步:各进程按照一定的顺序执行的过程.异步就不一定有顺序,而是随机的执行.一组并发进程进行互相合作,互相等待,使得各进程按照一定的顺序执行的过程.2.system系统调用可以按照字符串方式调用系统命令.3.生产者只需要释放信号量:消费量只需要获取而不需要释放4.信号量初始值等于0,在互斥通讯中大于05.生产者:(1)创建信号量集合的键值(ftok函数)(2)创建信号量(semget函数)(3)设置信号量初始值为0(semctl(信号量ID,第几个信号量,什么操作[,欲设置的值])函数)(

转载自~浮云比翼:Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)

Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥) 介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可以看作是Unix进程的表亲,同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等.但同一进程中的多个线程有各自的调用栈(call stack),自己的寄存器环境(register context),自己的线程本地存储(thread-local storage). 一

使用信号量控制Linux线程同步

线程同步 在现实生活中,有些东西就必须是按顺序执行的,只有我完成了以后,你才能在我的劳动成果上接着干:不能我还没有完成,你就开始干活了.这就是线程同步最直白的解释了. 在进行程序设计时,亦是如此.线程同步,同步的是什么?它同步的是对共享资源(内存区域,公共变量等)或者临界区域的访问.有的时候,这些共享 资源和临界区域,就只能容忍一个线程对它进行操作(读或者写,读操作一般不控制,主要是写操作),这个时候,我们必须要对这些共享资源或者临界区域进行同 步,那么如何对它们进行线程同步呢? 在Linux中

linux信号量之进程间同步

概念 linux信号量:允许多个线程同时进入临界区,可以用于进程间的同步. 和互斥锁(mutex)的区别:互斥锁只允许一个线程进入临界区. 所在头文件:semaphore.h 主要函数 初始化函数 int sem_init(sem_t *sem, int pshared, unsigned int value) sem:要初始化的信号量 pshared:此信号量是在进程间共享还是线程间共享 value:信号量的初始值 删除函数 int sem_destroy(sem_t *sem) sem:要销

linux应用开发-信号量互斥编程

linux应用开发-信号量互斥编程 一 相应的函数 1 创建/打开信号量集合 函数名 semget 函数原形 int semget(key_t key, int nsems, int semflg) 函数功能 获取信号量集合的标识符 当key所指的信号量不存在的时候,且semflg里包含了IPC_CREAT,就会创建一个信号量的集合 所属头文件 <sys/types.h> <sys/ipc.h> <sys/sem.h> 返回值 成功返回信号量的标识符 失败返回-1 参数

Linux多线程--使用信号量同步线程【转】

本文转载自:http://blog.csdn.net/ljianhui/article/details/10813469 信号量.同步这些名词在进程间通信时就已经说过,在这里它们的意思是相同的,只不过是同步的对象不同而已.但是下面介绍的信号量的接口是用于线程的信号量,注意不要跟用于进程间通信的信号量混淆,关于用于进程间通信的信号量的详细介绍可以参阅我的另一篇博文:Linux进程间通信——使用信号量.相似地,线程同步是控制线程执行和访问临界区域的方法. 一.什么是信号量 线程的信号量与进程间通信中