linux 下多进程的同步

      linux 多进程的同步:linux多进程我实现同步操作,操作单个信号量已经不能实现,对多进程的通信可以采取信号集的方式,一个信号集包含了多个信号量。

首先通过semget()创建信号量。例如:semid = semget(SEMKEY,2,0600|IFLAGS;

然后对信号集中各个信号量赋初值:

semctl(semid,0,SETVAL,0);

semctl(semid,1,SETVAL,1);

也可以通过 set_sem_value(semid,0,1),对信号集为semid重的第一个信号量赋初始值为1

void  set_sem_value(int semid,int num ,int val)
{
     union semun semun_info;
     semun_info.val=val;
     semctl(semid,0,SETVAL,semun_info);  
}

然后就是类似于PV原语的操作。

注意一下下面的这个机构体:
struct sembuf p1 = {0,-1,0},p2 = {1,-1,0},
v1 = {0,1,0},v2 = {1,1,0};

然后利用 int semop(int semid, struct sembuf *sops, unsigned nsops);  进行pv操作!。下面是具体的代码:

/**************************************produce.c*******************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>

#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include<errno.h>
#define SHMKEY (key_t) 0x100
#define SEMKEY (key_t) 0x200

#define IFLAGS (IPC_CREAT|IPC_EXCL)
#define ERR ((struct databuf *) -1)

struct databuf{
int d_buf[10];
};

static int shmid,semid;

pr_error(char *mess)
{
perror(mess);
exit(1);
}

getseg(struct databuf* *pdata)
{
    /*取得共享内存的key,如果还没建立的话,就建立(IPC_CREAT)*/
    if((shmid =shmget(SHMKEY,sizeof(struct databuf),0600|IFLAGS)) < 0)

    {
        if( errno == EEXIST)
        {
        shmid=shmget(SHMKEY,sizeof(struct databuf),0600|IPC_CREAT);
        if(shmid <0)
        pr_error("shmget");
        }
        else
        pr_error("shmget");

    }
    /*取得共享内存的指针,使用共享内存时可以和malloc分配的内存一样*/
    if((*pdata = (struct databuf *)(shmat(shmid,0,0))) == ERR)
    pr_error("shmat");
}
int getsem()
{ /*建立信号量(且称为A和B)*/
    if((semid = semget(SEMKEY,2,0600|IFLAGS)) < 0)
    {
    if(errno == EEXIST)

    {
    semid=semget(SEMKEY,2,0600|IPC_CREAT);
    if( semid <0)
    pr_error("semget");
    else
    /*加上这一句,如果已存在,不再初始化信号量*/
    return semid;
    }
    else
    pr_error("semget");
    }
    /*设置信号量A初值为0*/
    if(semctl(semid,0,SETVAL,0) < 0)
    pr_error("semctl");
    /*设置信号量B初值为1*/
    if(semctl(semid,1,SETVAL,1) < 0)
    pr_error("semctl");
    return(semid);
}

void remove_s()
{
    /*删除共享内存*/
    if(shmctl(shmid,IPC_RMID,NULL) < 0)
    pr_error("shmctl");
    /*删除信号量*/
    if(semctl(semid,IPC_RMID,NULL) < 0)
    pr_error("semctl");
}
main()
{
int semid;
struct databuf *buf;
semid = getsem();
getseg(&buf);
writer(semid,buf);
remove_s();
exit(0);
}

struct sembuf p1 = {0,-1,0},p2 = {1,-1,0},
v1 = {0,1,0},v2 = {1,1,0};

writer(int semid,struct databuf *buf)
{
int i,j;
for(i = 0;i < 10;i++){
/*P(B) B=0;准备写缓冲区*/
printf("next loop\n");
semop(semid,&p2,1);
/*写共享内存*/
for(j = 0;j < 10;j++){
buf -> d_buf[j] = 10 * i + j;
printf("buf->d_buf[%d]=%d\n",j,buf -> d_buf[j] );
}
sleep(5);
/*V(A) A==1,唤醒消费者进程,读缓冲区*/
semop(semid,&v1,1);

}
return;
}

 

/****************************consumer.c***************************/

 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>

#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include<errno.h>
#define SHMKEY (key_t) 0x100
#define SEMKEY (key_t) 0x200
 
#define IFLAGS (IPC_CREAT|IPC_EXCL)
#define ERR ((struct databuf *) -1)
 
struct databuf{
    int d_buf[10];
};
 
static int shmid,semid;
 
pr_error(char *mess)
{
    perror(mess);
    exit(1);
}
 
getseg(struct databuf* *pdata)
{
   /*取得共享内存的key,如果还没建立的话,就建立(IPC_CREAT)*/
   if((shmid =shmget(SHMKEY,sizeof(struct databuf),0600|IFLAGS)) < 0)
 
   {
      if( errno == EEXIST)
      {
         shmid=shmget(SHMKEY,sizeof(struct databuf),0600|IPC_CREAT);
         if(shmid <0)
           pr_error("shmget");
      }
      else
         pr_error("shmget");
   }
   /*取得共享内存的指针,使用共享内存时可以和malloc分配的内存一样*/
   if((*pdata = (struct databuf *)(shmat(shmid,0,0))) == ERR)
      pr_error("shmat");
}


int getsem()
{  /*建立信号量(且称为A和B)*/
   if((semid = semget(SEMKEY,2,0600|IFLAGS)) < 0)
   {
       if(errno == EEXIST)
       {
           semid=semget(SEMKEY,2,0600|IPC_CREAT);
           if( semid <0)
               pr_error("semget");
           else
           /*加上这一句,如果已存在,不再初始化信号量*/
               return semid;
       }
       else
          pr_error("semget");
   }
   /*设置信号量A初值为0*/
   if(semctl(semid,0,SETVAL,0) < 0)
      pr_error("semctl");
   /*设置信号量B初值为1*/
   if(semctl(semid,1,SETVAL,1) < 0)
      pr_error("semctl");
   return(semid);
}
 
 
main()
{
   int semid;
   struct databuf *buf;
   semid = getsem();
   getseg(&buf);
   reader(semid,buf);
   exit(0);
}
 
struct sembuf p1 = {0,-1,0},p2 = {1,-1,0},
v1 = {0,1,0},v2 = {1,1,0};
 
reader(int semid, struct databuf *buf)
{
   int i,j;
   for(i = 0;i <10;i++){
      /*P(A) A==-1,如果没数据的话,blocking,有的话,读*/
      printf("next loop\n");
      semop(semid,&p1,1);
      for(j = 0;j < 10;j++){
          printf(" %d ",buf -> d_buf[j]);
      }
      printf("\n");
      semop(semid,&v2,1);
      /*V(B) B++,唤醒写进程*/
   }
   return;
}
 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值