操作系统课设之Linux 进程管理

前言

课程设计开始了,实验很有意思,写博客总结学到的知识
白嫖容易,创作不易,学到东西才是真
本文原创,创作不易,转载请注明!!!
本文链接
个人博客:https://ronglin.fun/archives/173
PDF链接:见博客网站
CSDN: https://blog.csdn.net/RongLin02/article/details/118308366

为了美观,实验源代码在结尾处,整合版见下
链接:https://pan.baidu.com/s/1rXj1QJGuw-BVc5sQWret9w
提取码:Lin2
操作系统课程设计源代码
本次操作系统课程设计合集
操作系统课设之Windows 进程管理
操作系统课设之Linux 进程管理
操作系统课设之Linux 进程间通信
操作系统课设之Windows 的互斥与同步
操作系统课设之内存管理
操作系统课设之虚拟内存页面置换算法的模拟与实现
操作系统课设之基于信号量机制的并发程序设计
操作系统课设之简单 shell 命令行解释器的设计与实现
仅用于学习,如有侵权,请联系我删除

实验题目

Linux 进程管理

实验目的

通过进程的创建、撤销和运行加深对进程概念和进程并发执行的理解,明确进程和程序之间的区别。

实验内容

学习背景知识,了解Linux下的创建进程的方法。
由于操作系统的平时作业也是用Linux,再加上布置过在Linux下的C语言编程的作业,所以本验证性实验完成较为轻松
Linux环境:
虚拟机:Ubuntu 18.04 LTS;硬盘100G;内存4G;64位;4核心
Linux内核:5.11.8 开发工具:CodeBlocks
Linux虚拟机的安装可以看我这两篇博客:
https://blog.csdn.net/RongLin02/article/details/114273129
https://blog.csdn.net/RongLin02/article/details/115419994
原理:
主要涉及到两个函数,一个是fork(),一个是exec()系列函数
fork 会建立一个子进程,父进程继续运行,子进程在同样的位置执行同样的程序。fork()会分别返回两个值给父子进程,fork()返回子进程的 pid给父进程,fork()返回 0给子进程。出错时返回-1。 exec()函数会创建一个新的进程映象置换当前的进程映象。exec函数族的作用是根据指定的文件名找到可执行文件,并用它来取代调用进程的内容,换句话说,就是在调用进程内部执行一个可执行文件。这里的可执行文件既可以是二进制文件,也可以是任何Linux下可执行的脚本文件

在操作系统的平时作业中,我还用到了vfork()函数。因为fork()创建的子进程其实是父进程数据的copy,也就是说父子进程的数据并不是共享的,子进程只是父进程的翻版,类似于c语言函数中的传递形式参数,要想数据共享,其实也有很多方法,有些资料书上提到很多CLONE_开头的标志位就是控制哪些东西是父子进程共享的。不过有更简单的vfork()函数,其实本质上是一样的,都是调用内核函数do_fork()。需要注意的是,不论多进程还是多线程,数据一旦共享,会涉及到安全问题,不过vfork()创建子进程之后,父进程就会阻塞,所以就没安全问题了。
本验证实验不涉及到父子进程的数据传递

2-1 进程的创建

在Ubuntu下安装好CodeBlocks,然后用CodeBlocks,创建一个新工程,将指导书的代码copy到main.c文件中,然后编译运行查看结果
多次运行,查看结果
关键代码

    int x;
    srand((unsigned)time(NULL));
    while((x=fork())==-1);
    if (x==0)
    {
        sleep(rand() % 2);
        printf("a");
    }
    else
    {
        sleep(rand() % 3);
        printf("b");
    }
    printf("c");

2-2 子进程执行新任务

新建一个工程,将实例代码copy到main.c下
运行查看结果
关键代码

    pid_t pid;
    /* fork a child process */
    pid = fork();
    if (pid < 0)
    {
        /* error occurred */
        fprintf(stderr, "Fork Failed");
        return 1;
    }
    else if (pid == 0)
    {
        /* 子进程 */
        execlp("/bin/ls","ls",NULL);
    }
    else   /* 父进程 */
    {
        /* 父进程将一直等待,直到子进程运行完毕*/
        wait(NULL);
        printf("Child Complete\n");
    }

实验结果与分析

2-1 进程的创建

在这里插入图片描述
操作系统课设之Linux 进程管理_第1张图片
在这里插入图片描述
在这里插入图片描述
这是几次的运行的结果。
分析结果:
子进程输出a和c,父进程输出b和c,当fork()成功之后,将父进程的代码copy一份给子进程运行,所以说父子进程都会输出c,但是控制台只有一个,父子进程会抢输出,再加上一个随机睡眠函数,所以就会出现不同的输出结果。

2-2 子进程执行新任务

运行结果
操作系统课设之Linux 进程管理_第2张图片
子进程会执行execlp()调用ls命令,输出当前的目录结构,同时父进程因为用了wait(null),会自我阻塞,等待随机一个进程结束,然后再执行。
Wait函数也有两个,一个是wait(),另一个是waitpid(),后者比前者功能更强大。

小结与心得体会

由于操作系统平时作业的关系,我对于Linux系统也比较熟悉了,在Linux系统下的C/C++编程也比较熟悉,故完成本验证实验也很轻松。
平时作业我们曾完成过,Linux虚拟环境的安装,Linux内核的编译,Linux下的C语言的进程与线程编程,Linux下打印进程树。
这些在我的博客主页中都可以搜到
=w=

源代码

2-1 进程的创建

#include 
#include
#include 
#include 

int main()
{
    int x;
    srand((unsigned)time(NULL));
    while((x=fork())==-1);
    if (x==0)
    {
        sleep(rand() % 2);
        printf("a");
    }
    else
    {
        sleep(rand() % 3);
        printf("b");
    }
    printf("c");
    return 0;
}

2-2 子进程执行新任务

#include 
#include
#include 
#include 

int main()
{
    pid_t pid;
    /* fork a child process */
    pid = fork();
    if (pid < 0)
    {
        /* error occurred */
        fprintf(stderr, "Fork Failed");
        return 1;
    }
    else if (pid == 0)
    {
        /* 子进程 */
        execlp("/bin/ls","ls",NULL);
    }
    else   /* 父进程 */
    {
        /* 父进程将一直等待,直到子进程运行完毕*/
        wait(NULL);
        printf("Child Complete\n");
    }
    return 0;
}


你可能感兴趣的:(操作系统,linux)