简体   繁体   English

为什么在 c linux 中使用共享 memory 尝试 IPC 时出现分段错误

[英]Why am i getting segmentation fault when trying IPC using shared memory in c linux

problem: implement IPC between 3 processes in a way that the first process create the shared memory and then sends a signal to the second and third processes so they can get attached to that shared memory, now make the second process write something to the shared memory and then make it send a signal to the third process so that the third process reads what the second process had written.问题:在 3 个进程之间实现 IPC,第一个进程创建共享 memory,然后向第二个和第三个进程发送信号,以便它们可以连接到共享的 memory,现在让第二个进程向共享的 ZCD69B4957F06CD818D7BF3D3957F198CD8186 写入一些内容然后让它向第三个进程发送信号,以便第三个进程读取第二个进程写入的内容。

my code:我的代码:

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

static int pid0, pid1, pid2, shmid, status;

struct memory { 
    char msg[100];
}; 

struct memory* shmptr; 
struct sigaction act0, act1, act2;

// Handler For P0
void handler0(int signum) 
{ 
    if (signum == SIGUSR1) { 
        printf("Allowing P1 And P2 To Get Attached\n\n");
        kill(pid1, SIGUSR1); // Allow P1 To Get Attached
        kill(pid2, SIGUSR1); // Allow P2 To Get Attached
    } 

    if (signum == SIGUSR2) { 
        kill(pid1, SIGINT); // Kill P1 
        kill(pid2, SIGINT); // Kill P2 
    } 
} 

// Handler For P1
void handler1(int signum) 
{ 
    if (signum == SIGUSR1) { 
        
        // Attaching To The Shared Memory 
        shmptr = (struct memory*) shmat(shmid, 0, 0); 

        printf("P1 - Attached to: %d\n\n", shmid); 
    } 
} 

// Handler For P2
void handler2(int signum) 
{ 
    if (signum == SIGUSR1) { 
        
        // Attaching To The Shared Memory 
        shmptr = (struct memory*) shmat(shmid, 0, 0); 

        printf("P2 - Attached to: %d\n\n", shmid); 
    } 

    if (signum == SIGUSR2) { 

        printf("Message Read From Shared Memory Is: "); 
        puts(shmptr->msg); 

        status = 1;

        // Detaching P2 From The Shared Memory
        shmdt((void*)shmptr);
        
        kill(pid0, SIGUSR2);
    }
} 

int main() 
{
    status = 0;

    printf("P0\n\n");

    pid0 = getpid();

    // Key Of Shared Memory 
    key_t key = 123456;

    // Shared Memory Creation
    printf("Creating Shared Memory\n\n"); 
    shmid = shmget(key, sizeof(struct memory), IPC_CREAT | 0666); 

    // Attaching P0 To The Shared Memory 
    shmptr = (struct memory*)shmat(shmid, 0, 0); 
    printf("P0 - Attached to: %d\n\n", shmid);

    // Attaching Handler Function To Signal SIGUSR1 For Process 0
    act0.sa_handler = handler0;
    sigaction(SIGUSR1, &act0, NULL);
    printf("Forking...\n\n");
    
    pid1 = vfork();

    if(pid1 == 0){ // Inside P1

        printf("P1\n\n");
        
        // Attaching Handler Function To Signal SIGUSR1 For Process 1
        act1.sa_handler = handler1;
        sigaction(SIGUSR1, &act1, NULL);

        pid2 = vfork();

        if(pid2 == 0){ // Inside P2

            printf("P2\n\n");

            // Attaching Handler Functions To Signals SIGUSR1 And SIGUSR2 For Process 2
            act2.sa_handler = handler2;
            sigaction(SIGUSR1, &act2, NULL);
            sigaction(SIGUSR2, &act2, NULL);
            kill(pid0, SIGUSR1); // Tell P0 That P1 And P2 Are Ready To Get Attached To The Shared Memory
            
        } else { // Inside P1

            printf("P1 Again\n\n");

            // Writing A Message To The Shared Memory
            printf("Enter A Message: \n");
            fgets(shmptr->msg, 100, stdin); 

            // Sending The Message To Process 2
            kill(pid2, SIGUSR2); 
            printf("Sent Message To P2\n\n"); // this gets printed and then a segmentation fault error occurs
        }

    } else { // Inside P0
    
        printf("P0 - Waiting..\n\n");
        while(1){
            if(status == 1)
                break;
        }
        // Detaching P0 From The Shared Memory
        shmdt((void*)shmptr);

        shmctl(shmid, IPC_RMID, (struct shmid_ds *) NULL);
    }
}

after executing the printf("Sent Message To P2\n\n");执行完printf("Sent Message To P2\n\n"); i get a segmentation fault error我收到分段错误错误

please tell me why, i couldn't figure it out请告诉我为什么,我想不通

thanks谢谢

You can't do this with vfork() .你不能用vfork()做到这一点。

Read the man page, especially the part near the top where it says阅读手册页,尤其是靠近顶部的部分

the behavior is undefined if the process created by vfork() either modifies any data other than a variable of type pid_t used to store the return value from vfork(), or returns from the function in which vfork() was called, or calls any other function before successfully calling _exit(2) or one of the exec(3) family of functions.如果由 vfork() 创建的进程修改了用于存储 vfork() 返回值的 pid_t 类型变量以外的任何数据,或者从调用 vfork() 的 function 返回,或者调用任何其他 function 在成功调用 _exit(2) 或 exec(3) 系列函数之一之前。

暂无
暂无

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

相关问题 为什么我在尝试运行 find function 即使正确访问 memory 时遇到分段错误? - Why I am getting segmentation fault when trying to run the find function even though accessing memory properly? 为什么在尝试使用指针访问结构时会出现此分段错误? - why am i getting this segmentation fault when trying to access a struct using a pointer? C - 为什么我会出现分段错误? - C - Why am I getting a segmentation fault? 为什么在使用realloc()时出现分段错误? - Why am I getting a segmentation fault when using realloc()? IPC 通过共享内存和管道给出分段错误:C 中的 11 - IPC through shared memory and pipe gives segmentation fault: 11 in C 分配足够的内存后,为什么会出现“细分故障11”? - Why am I getting a “segmentation fault 11” when I have assigned enough memory? 为什么我使用 scanf 会出现分段错误? 我已经初始化并设置了 memory 大小,但仍然出现段错误 - Why am i getting a segmentation fault using scanf? I've initialized and set memory size, but still getting seg fault Linux共享内存分段错误 - Linux Shared Memory Segmentation Fault 为什么在尝试填充结构时出现分段错误(核心已转储)或总线错误(核心已转储)? - Why am I getting Segmentation fault (core dumped) or bus error (core dumped) when trying to populate a struct? C-处理共享内存时出现分段错误 - C - Segmentation fault when dealing with shared memory
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM