简体   繁体   中英

Access shared memory to child process with signal

I need some help with my c program. Basically, in my c program, I wish my parent process calculates a+b and my child process calculates 3*(a+b). However, I don't how to access the shared memory after sending the signal. Any help is appreciated.

#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);
}

What I have tried:

  1. Put one parameter in void sigcont(int shmid); As I am learning from https://www.geeksforgeeks.org/signals-c-set-2/ . Do signal() and kill() must use in pair? I get Thus, I tried to pass a value to it. Not working.

  2. Sigstop() and Sigcont() I tried to avoid using signal() in my child process so that I can access shmid directly. But I couldn't find a lot of examples of Sigstop() and Sigcont(). It fails as well.

It's really hard to get my desired result even it looks simple. Can anyone help with this? Any help is appreciated.

Notes: added error checking; call shmat() and save to global before fork() , child to inherit attached shared mem; SIGCONT better for stopped process, selected SIGUSR1 ; arg to sig handler is signal #; child was spinning, for minimal overhead better to pause() .

This version is an example, and does not attempt to support every system imagined.

#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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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