进程间的通信——共享空间篇

进程间的通信

众所周知,进程间的通信有多种,其中一种就是共享空间的使用


相关函数

在linux环境下进行进程间共享空间的操作,需要以下几个函数

创建或打开共享存储区(shmget)

  • 依据用户给出的整数值key,创建新区或打开现有区
  • 返回一个共享存储区ID。

连接共享存储区(shmat)

  • 连接共享存储区到本进程的地址空间
  • 返回共享存储区首地址
  • 父进程已连接的共享存储区可被fork创建的子进程继承。

拆除共享存储区连接(shmdt)

  • 拆除共享存储区与本进程地址空间的连接。

共享存储区控制(shmctl)

  • 对共享存储区进行控制。
  • 如:共享存储区的删除需要显式调用shmctl(shmid, IPC_RMID, 0);

用系统调用ftok给出IPC键值key

  • 保证同一个用户的两个进程获得相同的IPC键值key

实验题目

  • 在子进程创建Fibonacci序列,并存储在共享空间钟
  • 在父进程访问共享空间,并输出子进程创建的序列

实践内容

  • 代码如下
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/stat.h>

#define MAX_SIZE 10

struct fibonacci
{
    int fib_seq[MAX_SIZE];
    int size;
};


int main(int argc, char*argv[])
{   
    int f0 = 0, f1 = 1, f2 = 0;

    if(argc != 2) {
        fprintf(stderr, "Please input:the name of the program and a num\n");
        fprintf(stderr, "eg:./a.out 5\n");
        exit(0);
    }

    if(atoi(argv[1]) > 10) {
        fprintf(stderr, "the num is too large");
        exit(0);
    }
    if(atoi(argv[1]) < 2) {
        fprintf(stderr, "the num is too small");
        exit(0);
    }

    key_t kid;
    kid = shmget(IPC_PRIVATE, MAX_SIZE, S_IRUSR|S_IWUSR);

    struct fibonacci* fib = (struct fibonacci*)shmat(kid, NULL, 0);
    fib->size = atoi(argv[1]);
    //fib->size = 5;

    pid_t pid = fork();

    if(pid < 0) {
        fprintf(stderr, "cteate child failed");
    }
    else if(pid == 0) {
        fib->fib_seq[0] = f0;
        fib->fib_seq[1] = f1;

        for(int i = 2; i < fib->size; i++) {
            f2 = f0 + f1;
            f0 = f1;
            f1 = f2;
            fib->fib_seq[i] = f2;
        }
        printf("the child process is complete\n");
        exit(0);
    }
    else {
        wait(NULL);
        for(int i = 0; i < fib->size; i++) {
            printf("%d ", fib->fib_seq[i]);
        }
        printf("\nfinish!\n");
    }

    shmctl(kid, IPC_RMID, NULL);
    return 0;
}
  • 实验截图
    这里写图片描述
  • 实验思路
    利用上面的函数,现在父进程钟创建一个共享空间,在父进程创建一个子进程,此时该子进程继承了父进程的共享空间。之后父进程等待子进程创建序列,创建完成后结束子进程,父进程访问共享空间进行读取输出即可。

实验难点

  • 感觉其实共享空间的使用并不难,有个坑就是在于运行程序时,参数的输入。
  • 一直以为输入的参数是存在argv[0]中,其实是储存在argv[1]中

猜你喜欢

转载自blog.csdn.net/qq_36312878/article/details/80154998