父子进程通过共享内存进行通信的进程间通信

题目   父子进程通过共享内存进行通信。

比如:父进程收到信号SIGUSR1,写共享内存。

 子进程收到信号SIGUSR2,读共享内存

        流程如下:

                    1、先求key的值

                    2、创建并打开共享内存

                    3、映射

                    4、创建 父子子进程 

                    5、父进程中安装信号 写入数据然后给子进程发送信号,等待子进程的信号 然后读取数据

                    6、子进程中安装信号 等待父进程写数据  父进程写完发出的数据被子进程接收到 ,然后子进程开始读取数据,然后再给共享内存中写入数据,再发送信号给父进程

                    7、解除映射。删除共享内存

        代码如下

            

/*************************************************************************
	> File Name: 1.c
	> Author: 
	> Mail: 
	> Created Time: 2018年06月11日 星期一 18时26分47秒
 ************************************************************************/

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

#define BUF_SIZE 100
#define SHM_SIZE 1024

void handler1(int sig)
{
    if ( SIGUSR1 == sig )
    {
		printf("\t\t父进程已经写好数据\r\n");
    }
}

void handler2(int sig)
{
    if ( SIGUSR2 == sig )
    {
		printf("\t\t子进程已经写好数据\r\n");
    }
}

int main(void)
{
    key_t key = 0;
    int ret = 0;
    int shmid = 0;
    pid_t pid;
    char * pShm = NULL;
    char buf[BUF_SIZE] = {'\0'};

    //key
    key = ftok( "/tmp", 23 );
    if ( 0 > key )
    {
        perror("ftok error");
        return -1;
    }

    //创建并且打开共享内存
    shmid = shmget(key, SHM_SIZE, 0644 | IPC_CREAT);
    if ( 0 > shmid )
    {
        perror("shmget error");
        return -1;
    }

    //映射
    pShm = shmat(shmid, NULL, 0);
    if ( (void *)-1  == pShm )
    {
        perror("shmat error");
        shmctl(shmid, IPC_RMID, NULL);
        return -1;
    }

    //创建子进程
    pid = fork();
    if ( 0 > pid )
    {
        perror("fork error");
        shmctl(shmid, IPC_RMID, NULL);
        return -1;
    }
    else if ( 0 < pid )
    {
        //安装信号
        signal(SIGUSR2, handler2);
        while(1)
        {
            printf("父进程对子进程说:");
            //向共享内存中写入数据
            fgets(pShm, SHM_SIZE, stdin);
            //数据写入完成,向子进程发送信号
            kill(pid,SIGUSR1);

            //等待子进程信号
            pause();
            //读取共享内存中数据
            printf("父进程读取:%s\r\n",pShm);
            
            //输入#时结束父程序,并向子进程发送信号
            if ( '#' == pShm[0] ) 
            {
                kill(pid, SIGUSR1);
                break;
            }
        }
        printf("父进程结束!\n");
        
        //映射
        shmdt(pShm);

        //删除共享内存
        shmctl(shmid, IPC_RMID, NULL);
    }
    else
    {
        //获取父进程ID
        pid_t ppid;
        ppid = getppid();
        //安装信号
        signal(SIGUSR1, handler1);
        //等待父进程信号
        while(1)
        {
			//等待父进程写数据
            pause();
            //读取输出共享内存中的数据
            printf("子进程读取:%s\r\n",pShm);
            printf("子进程对父进程说:");
            //向共享内存写入数据
            fgets(pShm, SHM_SIZE, stdin);
            //数据写入完成,向父进程发送信号
            kill(ppid,SIGUSR2);
            //输入#时结束父程序,并向子进程发送信号
            if ( '#' == pShm[0] ) 
            {
                kill(ppid, SIGUSR2);
                break;
            }
        }
        printf("子进程结束!\n");
    }
    return 0;
}




猜你喜欢

转载自blog.csdn.net/nbdr_yl/article/details/80669742