【问题标题】:Access shared memory to child process with signal使用信号访问共享内存到子进程
【发布时间】:2020-10-05 15:38:48
【问题描述】:

我的 c 程序需要一些帮助。基本上,在我的 c 程序中,我希望我的父进程计算 a+b,而我的子进程计算 3*(a+b)。但是,我不知道在发送信号后如何访问共享内存。任何帮助表示赞赏。

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

void sigcont(int shmid); 

int main (int argc, char *argv[]){
    int shmid;
    int *result;
    pid_t pid;

    int size_data = 2 * sizeof (int);
    shmid = shmget (IPC_PRIVATE, size_data, 0666 | IPC_CREAT);
    
    pid = fork ();
    if (pid == 0) {
        signal(SIGCONT, sigcont); 
        while (1);
    }
    else {
        sleep(1);
        result = (int *) shmat (shmid, NULL, 0);
        result[0] = atoi (argv[2]) + atoi (argv[1]);
        printf ("Result in parent process %d: %d.\n", getpid() , result[0]);
        printf ("Send a SIGCONT to process %d.\n\n", pid);
        shmdt (result);
        kill (pid, SIGCONT);
        wait(NULL);
        printf ("\nThis is the End.\n");
    }
  return 0;
}

void sigcont(int shmid){
    printf("Get a SIGCONT.\n");
    printf("Result in child process ID: %d.\n", getpid());
    exit(0);
}

我尝试过的:

  1. 在void sigcont(int shmid)中放一个参数; 正如我向https://www.geeksforgeeks.org/signals-c-set-2/ 学习的那样。 signal() 和 kill() 必须成对使用吗?我明白了因此,我试图向它传递一个值。不工作。

  2. Sigstop() 和 Sigcont() 我试图避免在我的子进程中使用 signal() 以便我可以直接访问 shmid。但是我找不到很多 Sigstop() 和 Sigcont() 的例子。它也失败了。

即使看起来很简单,也很难得到我想要的结果。有人能帮忙吗?任何帮助表示赞赏。

【问题讨论】:

    标签: c signals ipc shared-memory


    【解决方案1】:

    注意:增加了错误检查;调用shmat() 并在fork() 之前保存到全局,子级继承附加的共享内存; SIGCONT 更适合停止的进程,选择SIGUSR1; arg 到 sig 处理程序是信号 #;孩子在旋转,为了最小的开销最好pause()

    这个版本只是一个例子,试图支持所有想象的系统。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/wait.h>
    #include <unistd.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    
    int *shmloc;
    
    
    void shandler(int sig)
    {
        printf("pid %d, sig %d\n", getpid(), sig);
        printf("mult result: %d\n", *shmloc * 3);
    }
    
    
    int main(int argc, char *argv[])
    {
        int a, b, shmid, size_data, sig;
        pid_t pid;
    
        if (argc < 3) {
            fprintf(stderr, "missing args a b\n");
            return (1);
        }
    
        // OP: shmget() size arg, some systems may require a minimum, may roundup
        size_data = 2 * sizeof (int);
        shmid = shmget(IPC_PRIVATE, size_data, 0666 | IPC_CREAT);
        if (shmid == -1) {
            fprintf(stderr, "shmget failed, %s\n", strerror(errno));
            return (1);
        }
    
        shmloc = shmat(shmid, NULL, 0);
        if (shmloc == (void *) -1) {
            fprintf(stderr, "shmat failed, %s\n", strerror(errno));
            return (1);
        }
    
        sig = SIGUSR1;
        pid = fork();
        if (pid < 0) {
            fprintf(stderr, "fork failed, %s\n", strerror(errno));
            return (1);
        }
    
        // child only
        if (pid == 0) {
            signal(sig, shandler); 
            pause();
            printf("child exit\n");
            _exit(0);
        }
    
        sleep(1);
        // OP: care about non-digits in cmd-line args?
        a = atoi(argv[1]);
        b = atoi(argv[2]);
        *shmloc = a + b;
        printf("parent pid %d, add (%d, %d) result %d\n", getpid(), a, b, *shmloc);
        shmdt(shmloc);
        printf("sending signal %d to child %d\n", sig, pid);
        kill(pid, sig);
        wait(NULL);
        printf("\nThis is the End.\n");
    
        return (0);
    }
    

    【讨论】:

    • 谢谢你的回答。如果我想使用 Sigstop() 和 Sigcont() 怎么办?我想一开始就停止子进程,然后运行父进程。得到a+b后,父进程发送信号给子进程继续。是否可以?我该怎么做?
    • 这意味着如果我使用 sigstop 而不是 pause(),它会起作用吗?
    猜你喜欢
    • 1970-01-01
    • 2012-01-11
    • 2010-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 2020-09-06
    相关资源
    最近更新 更多