操作系统概念第七版习题 3.10 代码详解

操作系统概念第七版习题 3.10代码详解

代码应该可以直接用

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <wait.h>
#define PERM S_IRUSR|S_IWUSR    //IPC_PRIVATE            保证使用唯一ID(或key)
                                //S_IRUSR | S_IWUSR      使当前用户可以读写这个区域

#define MAX_SEQUENCE 10

typedef struct Shared_data   //定义结构体  而且保证不用写struct
{
    long fib_sequence[MAX_SEQUENCE];
    int sequence_size;
}shared_data;  //创建一个别名 为shared_data的类型

int main(int argc, char **argv)
{
    //step1------------------------------------------
    key_t shmid;   //定义shmid
    shared_data *p_addr, *c_addr;  //定义两个指针 p_addr表示父进程中指向共享内存区域的指针, c_addr表示子进程中指向共享内存区域的指针
    pid_t pid;   //进程号

    if (argc != 2) { //如果传入参数不合法就输出样式
         fprintf(stderr, "Usage:./a.out fib_size\n\a"); 
         exit(1);
    }
    if (atof(argv[1])> 10 || atof(argv[1]) < 1) {   //判断数组大小合法性
        fprintf(stderr, "use number between 1~10\n\a"); 
        exit(1);
    }



    // step2------------------------------------------

    shared_data store;   //建立一个struct  用来暂时存储一个shared_data

    store.sequence_size = atof(argv[1]);    //把命令行参数传给shared_data

    // step3------------------------------------------

    if( (shmid = shmget(IPC_PRIVATE, 1024, PERM)) == -1 )   { //分配共享内存区
        fprintf(stderr, "Create Share Memory Error:%s\n\a", strerror(errno));
        exit(1);
    }

    p_addr = shmat(shmid, 0, 0);  
        //连接共享内存区      
    memset(p_addr, '\0', sizeof(shared_data));  
        //把数据先清零

    for(int i = 0; i < MAX_SEQUENCE; i++) {
        p_addr->fib_sequence[i] = store.fib_sequence[i];
    }   

    p_addr->sequence_size = store.sequence_size;

    //把数值赋给共享内存中的数值

    pid = fork();  //创建子进程

    if(pid > 0) {    //如果是父进程

        //在共享内存区存入一个类型为shared_data的数据store  此数据已经存储了 命令行参数

        wait(NULL);   
        //等待子进程结束,结束算完fib数列

        for (int i = 0; i < p_addr->sequence_size; i++) {
            printf("%ld ", (p_addr->fib_sequence[i]));  
        }
        //打印结果

        exit(0);
    }
    else if (pid == 0){      //如果是子进程, 则计算斐波那契数列 更新共享内存的数据
        c_addr = shmat(shmid, 0, 0);
        //连接内存共享区

        //下面计算斐波那契数列
        c_addr->fib_sequence[0] = 1;
        c_addr->fib_sequence[1] = 1;
        //直接开始就是设置0和1的位置是1 然后后面的开始算就好,因为打印是根据size来打印的,而且第一位和第二位都是1
        for (int i = 2; i < c_addr->sequence_size; i++) {
            c_addr->fib_sequence[i] = c_addr->fib_sequence[i-1] + c_addr->fib_sequence[i-2];
        }


        exit(0);
        //退出子进程
    }

    return 0;
}
posted @ 2018-04-27 21:45  qq874455953  阅读(493)  评论(0编辑  收藏  举报