繁体   English   中英

信号量和共享内存

[英]Semaphore and shared memory

我尝试编写一个由信号灯同步的2个进程的程序。 父进程会生成一个随机数,并将其保存到共享内存中。 孩子读这个号码。 仅在父级完成生成后才能读取,而父级只有在子级读取后才能生成新编号。

我不知道我的程序是否正常运行,因为在尝试访问data->random_num = random;时遇到了段错误data->random_num = random; data->random_num;

代码是:

#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <unistd.h>

#include <time.h>
#include <stdlib.h>

const key_t sem_key = (key_t)0x12345678;
const key_t shm_key = (key_t)0x12339678;

struct shared_data{
  int random_num;
};

union semun{
  int val; //setval value
};

int sem_wait(int semafor_id){
  struct sembuf sb;
  sb.sem_num = 0;
  sb.sem_op = -1;
  sb.sem_flg = SEM_UNDO;

  return semop(semafor_id,&sb,1);
}

int sem_signal(int semafor_id){
  struct sembuf sb;
  sb.sem_num = 0;
  sb.sem_op = 1;
  sb.sem_flg = SEM_UNDO;

  return semop(semafor_id,&sb,1);
}

int main(int argc,char* argv[]){

  int status;

  srand(time(NULL));
  //Create shared memory
  int memory_id = shmget(shm_key,sizeof(struct shared_data),0600|IPC_CREAT|IPC_EXCL);
  if(memory_id < 0){
    printf("Shared memory creating failed\n");
    return 1;
  }

  //Create semafor
  int semafor_id = semget(sem_key,10, 0600|IPC_CREAT|IPC_EXCL);
  if(semafor_id < 0){
    printf("SEMAFOR creating failed\n");
    return 1;
  }
  semctl(semafor_id,0,SETVAL,1); //init semafor

  pid_t pid = fork();
  if(pid < 0){
    printf("FORK FAILED\n");
  }
  else if(pid > 0){

    printf("PARENT\n");
    int i;
    if(i = sem_wait(semafor_id) < 0){
      printf("Failed wait parent\n");
      return 1;
    }else{
      int random = rand() % 80;
      printf("Generate random number: %d\n",random);
      //Try attach memory for writting     
      void* address = shmat(memory_id, NULL ,0);
      if(address == NULL){
        printf("Failed to atach memory\n");
        return 1;
      }

      struct shared_data* data = (struct shared_data*) address;
      data->random_num = random;

      if(shmdt(address) != 0){
        printf("Failed to detach shared memory\n");
      }

      sleep(2); 
    }

    if(i = sem_signal(semafor_id) < 0){
      printf("Failed signal parent\n");
    }else{
      printf("Parent leave generating number\n");
    }

    //wait for child
    wait(&status);
    printf("Destroy semafor\n");
    semctl(semafor_id,0, IPC_RMID,0);
    printf("Destroy shared memory\n");
    shmctl(memory_id,IPC_RMID, 0);

    return 0; 
  }
  else{
    printf("CHILD\n");
    int j;
    //try to get semafor
    if(j = sem_wait(semafor_id) < 0){
      printf("FAILED wait child\n");
    }else{
      printf("Child reading data\n");
      void* address = shmat(memory_id, NULL ,0);
      if(address == NULL){
        printf("Failed to atach memory in child\n");
        return 1;
      }

      struct shared_data* data = (struct shared_data*) address;
      printf("Child read data %d\n",data->random_num);
      sleep(1);

      if(shmdt(address) != 0){
        printf("Failed to detach shared memory in child\n");
      }
    }   

    if(j = sem_signal(semafor_id) < 0){
      printf("Failed signal child\n");
    }else{
      printf("Leave data reading\n");
    }
    return 0;
  }

  return 0;
}
void* address = shmat(memory_id, NULL ,0);

我在该行(以及另一处称为shmat的行)上收到此错误:

warning: initialization makes pointer from integer without a cast

手册页中说shmat返回一个空指针,所以这可以提示某些错误。 事实证明,添加此行(以获取缺少的原型)可以解决此问题:

#include <sys/shm.h>

编辑:上面替换了一个先前的答案,这是一个红色的鲱鱼。

PS它有助于在测试时从标志中删除IPC_EXCL,因此,如果发生崩溃,则不必不断进行ipcs / ipcrm洗牌,而无需先删除现有的段/信号即可创建新的段/信号。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM