当前位置: 首页 > 知识库问答 >
问题:

用C语言处理信号量和共享内存

贝德辉
2023-03-14

程序应该创建200000个整数,并将2000个写入共享内存。分叉进程应该从共享内存中读取2000,父进程应该将下一个2000写入共享内存。

    #include <stdio.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <sys/sem.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <sys/resource.h>
    #include <sys/wait.h>

    #define N_DATA 200000
    #define N_SHARED 2000
    #define LOCK       -1
    #define UNLOCK      1

    static struct sembuf semaphore;

    char shmidArg[32];
    char semidArg[32];
    int *shmData;
    int i, j;
    int status;
    char *strsignal(int sig);
    pid_t pid;

    static int shmid;
    static int semid;

    char *strsignal(int sig);

    /** Semaphore Operation */
    static int semaphore_operation (int op) {
       semaphore.sem_num = 1;
       semaphore.sem_op = op;
       semaphore.sem_flg = IPC_NOWAIT;
       if( semop (semid, &semaphore, 1) == -1) {
          perror(" semop ");
          exit (EXIT_FAILURE);
       }
       return 1;
    }

    int main(int argc, char **argv) {
      /* Ein Shared-Memory-Segment einrichten */
      shmid = shmget(IPC_PRIVATE, N_SHARED*sizeof(int), IPC_CREAT | SHM_R | SHM_W);
      if (shmid == -1) {
       perror("shmid");
       exit(1);
      }

      printf("Shared-Memory-ID: %d\n",shmid);

      /* Pointer zu Shared-Memory-Segment erhalten */
      shmData = (int *)shmat(shmid,0, 0);
      if (shmData == (int *)(-1)) {
          perror("shmat");
          exit(1);
      }

      /* Semaphore anlegen */
      semid = semget(IPC_PRIVATE, 1, IPC_CREAT | SHM_R | SHM_W);
      if (semid < 0) {
       perror("semid");
       exit(1);
      }

      printf ("Semaphor-ID : %d\n", semid);

      /* Semaphor mit 1 initialisieren */
    if (semctl (semid, 0, SETVAL, (int) 1) == -1) {
       perror("semctl");
    }

    snprintf(shmidArg,32, "%d", shmid);
    snprintf(semidArg,32, "%d", semid);

      /** erstellen des Kindprozesses */
      pid = fork();

      // Kindprozess
      if (pid == 0) {
        execlp("./shm_child",shmidArg,semidArg,NULL);
      } else if (pid < 0) {
            perror("Kindprozess konnte nicht erzeugt werden!");
            return 1;
        }
      // Elternprozess
      else {
        /** ininitalisieren des Zufallsgenerator durch aktuellen Zeitstempel */
        srand48(time(NULL));
        for(i=0;i<N_DATA;i=i+N_SHARED) {
          semaphore_operation(LOCK);
          for (j=0; j<N_SHARED; j++) {
            shmData[j] = lrand48();
            //MSZ
            //printf("SHM-->%d-->%d\n",i+1,shmData[i]);
          }
    //      if(i == 0 || i == 2000) {
            printf("Parent-->%d-->0-->%d\n",i,shmData[0]);
            printf("Parent-->%d-->1999->%d\n",i,shmData[1999]);
    //      }
          semaphore_operation(UNLOCK);
          //sleep(1);
        }
      }

      //MSZ
      //sleep(2);
      printf("PID: %d\n", pid);

      if (waitpid(pid, &status, 0) == -1) {
            perror("wait konnte nicht erzeugt werden!");
            return 1;
        }

        if (WIFEXITED(status)) {
            printf("Exitcode: %d\n", WEXITSTATUS(status));
        semctl (semid, 0, IPC_RMID, 0);
        shmctl (shmid, IPC_RMID, NULL);
        //If process terminaded by a signal
        } else if (WIFSIGNALED(status)) {
            printf("Signal: %d %s\n", WTERMSIG(status), strsignal(WTERMSIG(status)));
        semctl (semid, 0, IPC_RMID, 0);
        shmctl (shmid, IPC_RMID, NULL);
        }

    }
        #include <stdio.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <sys/sem.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>

    #define N_DATA 6000
    #define N_SHARED 2000
    #define LOCK       -1
    #define UNLOCK      1

    int i,j;
    int *shmData;
    static int shmid;
    static int semid;
    static struct sembuf semaphore;


    /** Semaphore Operation */
    static int semaphore_operation (int op) {
       semaphore.sem_num = 0;
       semaphore.sem_op = op;
       semaphore.sem_flg = SEM_UNDO;
       if( semop (semid, &semaphore, 1) == -1) {
          perror(" semop ");
          exit (EXIT_FAILURE);
       }
       return 1;
    }

    int main(int argc, char **argv) {
      shmid = atoi(argv[0]);
      semid = atoi(argv[1]);

      printf("\nshm_child shared memoryid:%d\n",shmid);
      printf("shm_child Semaphoren-ID:%d\n",semid);

      /* Pointer auf Shared-Memory erstellen */
      shmData = (int *)shmat(shmid,0,0);
      if (shmData == (int *)(-1)) {
          perror("shmat");
          exit(1);
      }


    for(i=0;i<N_DATA;i=i+N_SHARED) {
      semaphore_operation(LOCK);
      for(j=0;j<N_SHARED;j++) {
        //printf("%d-->%d --> %d\n",i,j+1,shmData[j]);
      }
    //  if(i == 0 || i == 2000) {
        printf("child-->%d-->0-->%d\n",i,shmData[0]);
        printf("child-->%d-->1999->%d\n",i,shmData[1999]);
    //  }
      semaphore_operation(UNLOCK);
      sleep(1);
    }

      return 0;
    }

请帮帮我们谢谢你们

编辑:非常感谢您的回答。我不能标出正确的答案,因为我不知道什么是正确的。但我不想再尝试了。15个小时就够了

共有1个答案

孙子民
2023-03-14

写入进程应给予读者阅读许可,并等待阅读完成。在此之后,读者应允许作者继续写作,并等待写作完成。

这个目标不能用单个信号量来实现。你需要两个,大致如下:

    // parent aka writer
    writer_barrier = semaphore(UNLOCKED);
    reader_barrier = semaphore(LOCKED);
    start_reader();
    while(...) {
        lock(writer_barrier);
        write_data();
        unlock(reader_barrier);
    }

    // child aka reader
    while(....)
        lock(reader_barrier);
        read_data();
        unlock(writer_barrier);
    }
 类似资料:
  • 我尝试编写一个共享内存和信号量程序,该程序一直运行到按下Ctrl+C,即接收到: 当按下Ctrl+C时,被设置为,它会跳出循环并退出。在没有共享内存和信号量的情况下,这可以很好地工作,但是在这里,我从来没有在上获得字符串,只捕获并且它继续运行。 为什么?

  • 我想创建一个共享内存和信号量的C程序。应该有两个子进程。两个孩子都有一个不同的int数。然后有一个目标号码,应该写在共享内存中。现在两个孩子都应该从进球数中减去他们的数字,直到进球数低于或等于0。我不希望出现比赛条件。这就是为什么我尝试使用信号量。但对我没用。下面是我的代码:

  • 我不太了解共享内存是如何工作的,我试图编写一个服务器-客户机程序,在该程序中,服务器和客户机使用共享内存和信号量相互通信。

  • 我需要编写一个程序,它正在创建N个数量的子进程,每一个进程都将一个添加到共享内存变量中。我的想法是使用信号量和共享内存,但进程之间并没有相互等待,共享内存变量也没有像我希望的那样工作。 MyDefs.H Main.C 奴隶Proc.c