bai_jimmy

导航

Linux进程通信-共享内存

 

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

#include <sys/sem.h>

int fd[2];
int semid;
union semun{
        int val;
        struct semid_ds *ds;
        unsigned short *array;
};

void init_sem()
{
        if((semid = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | 0777)) < 0){
                perror("semget error");
                exit(1);
        }
}

void init_pipe()
{
        if(pipe(fd) < 0){
                perror("create pipe error");
                exit(1);
        }
}

void wait_pipe()
{
        char c;
        if(read(fd[0], &c, sizeof(char)) < 0){
                perror("read error");
                exit(1);
        }
}

void wait_sem()
{
        struct sembuf ops = {
                0, -1
        };
        semop(semid, &ops, 1);
}

void notify_pipe()
{
        char c = 'c';
        if(write(fd[1], &c, sizeof(char)) != sizeof(char)){
                perror("write error");
                exit(1);
        }
}

void notify_sem()
{
        struct sembuf ops = {
                0, 1, IPC_NOWAIT
        };
        semop(semid, &ops, 1);
}

void destroy_pipe()
{
        close(fd[0]);
        close(fd[1]);
}

void destroy_sem()
{
        semctl(semid, 0, IPC_RMID, NULL);
}

int main()
{
        //创建共享内存...
        int shmid;
        if((shmid = shmget(IPC_PRIVATE, 1024, IPC_CREAT | IPC_EXCL | 0777)) < 0){
                perror("shmget error");
                exit(1);
        }

        //init_pipe();
        init_sem();
        pid_t pid = fork();
        if(pid > 0){
                //父进程,映射共享内存
                int *shmaddr = shmat(shmid, 0, 0);
                if(shmaddr == (int *) -1){
                        perror("shmat error");
                        exit(1);
                }
                //向共享内存中写入数据(通过操作共享内存的映射地址即可)
                *shmaddr = 100;
                *(shmaddr + 1) = 200;
                //解除共享内存绑定
                shmdt(shmaddr);
                sleep(6);
                //通知子线程
                //notify_pipe();
                notify_sem();
                //等待子进程结束
                wait(0);
                //删除共享内存
                shmctl(shmid, IPC_RMID, NULL);
                //回收管道
                //destroy_pipe();
                destroy_sem();
        }else if(pid == 0){
                //等待父进程写入完成
                //wait_pipe();
                printf("wait for parent...\n");
                wait_sem();
                int *shmaddr = shmat(shmid, 0, 0);
                if(shmaddr == (int *) -1){
                        perror("shmat error");
                        exit(1);
                }
                int start = *shmaddr;
                int end = *(shmaddr + 1);
                printf("start = %d, end = %d\n", start, end);
                shmdt(shmaddr);
                //destroy_pipe();
        }else{
                perror("fork error");
                exit(1);
        }
        return 0;
}

 

posted on 2017-02-05 13:42  bai_jimmy  阅读(165)  评论(0编辑  收藏  举报