Linux进程通信之同步进程
上一篇我讲了Linux进程通信之信号量的相关知识,本节我将学习Linux的进程同步,因为在Linux中进程的同步我采用了信号量的方法来完成,因此有关信号量的知识大家可以看我上一篇博客介绍,在此就不再赘述了。
所谓的进程同步就是指一组并发进程进行互相合作、互相等待,使得各进程按一定的顺序执行的过程。在我们进程同步的问题中,有一个非常经典的问题,就是生产者与消费者问题,这个在我们学习的多项领域中都被采用过,今天我也以这个例子来说一下Linux中进程同步问题。
在上一篇博客中,我也是以两个进程通信来进行讲解的,而且也是信号量,那么今天讲解的和上一篇有何不同?在上一篇,我用的信号量方式是互斥信号量,两个进程是没有先后顺序的,谁先运行谁就先获得信号量,因此在最开始信号量是默认有值的。而在同步进程中,两个进程必须是有严格顺序的,比方说我们的生产者与消费者,肯定是先有生产者生产了产品,消费者才能消费,如果生产者没有生产好产品,消费者即使来了,也不能消费,只能等待生产者生产后再消费,而且在这个问题中,产品就类似我们的信号量,生产者只释放信号量,而消费者只获取信号量,在初始的时候,信号量的初值应该是0,因为最初的时候,没有任何产品存在,只有等生产者生产了产品之后释放了信号,才可以改变信号量的值。下面我们就用一个程序来感受一下:
生产者productor:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/sem.h>
void main()
{
int fd;
key_tkey;
int semid;
struct sembuf sops;
key = ftok("/home" , 1); //创建一个与信号对应的键值
semid = semget(key , 1 , IPC_CREAT); //创建一个信号量
//这里必须将创建的信号量的初始值设为0,
//因为生产者只有生产了产品,消费者才能获取
//生产者生产了产品,释放信号,此时消费者才能获取信号,从而获取产品
semctl(semid , 0 , SETVAL , 0);
//将一个文件作为生产者的产品
fd = open("./product.txt" ,O_RDWR|O_CREAT ,0777);
sleep(20); //休眠20s
write(fd , "just a product!" ,16);
close(fd);
//生产完产品释放信号
sops.sem_num = 0;
sops.sem_op = 1;
sops.sem_flg = SEM_UNDO; //这个必须要设置,不然容易让semop函数失败
semop(semid , &sops ,1);
}
消费者customer:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdlib.h>
/***************************
这里消费者将生产者生产的产品(文件)复制到另一个地方表示获得这个产品
****************************/
void main()
{
key_t key;
int semid;
struct sembuf sops;
key = ftok("/home" , 1); //创建一个与信号对应的键值
semid = semget(key , 1 , IPC_CREAT); //打开一个信号量
//获取信号量,如果没有信号,就等待
sops.sem_num = 0;
sops.sem_op = -1; //负数表示获取信号量
sops.sem_flg = SEM_UNDO; //这个必须要设置,不然容易让semop函数失败
semop(semid , &sops ,1);
//该函数的作用就是执行参数的命令,这里就是复制生产者的产品到另一个位置
system("cp ./product.txt./test/");
}
程序中相关语句都做了非常详细的解释,有关信号量的操作的知识,大家可以看我前一篇博客。这两个程序的功能是:
生产者创建一个产品,这里用创建一个文件和向文件写入数据来表示这个产品,创建完成后,释放信号,。
消费者一开始就获取信号,但此时信号值为0,所以它就一直等待生产生产产品,以获得信号,然后执行将产品(文件)复制到一个test目录下。
执行我们程序,应该是消费者一直等待生产者执行完后才执行完,同时在我们的test目录下有我们的相应复制的文件。
以上便是进程同步中经典的生产者与消费者问题,如有不全,希望得到大家的指正。