打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
linux 下多进程的同步 [共享内存和信号量]
[转]http://blog.csdn.net/juckciy/article/details/6884422

 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);    
/*xulm  int semop(int semid, struct sembuf semoparray[], size_t nops);  semoparray是一个指针,它指向一个信号量操作数组。nops规定该数组中操作的数量。 */

/*写共享内存*/ 
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; 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
Linux System V信号量&POSIX信号量区别
linux信号量_閑の洎茬
获取信号量信息 利用信号量实现共享资源的申请和释放
C++通过信号量控制共享内存的读写
System V semaphore: semget() semop() semctl()...
Linux环境进程间通信(四)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服