Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【Linux程序设计】之进程控制&守护进程

【Linux程序设计】之进程控制&守护进程

作者头像
马三小伙儿
发布于 2018-09-12 07:05:22
发布于 2018-09-12 07:05:22
2.1K00
代码可运行
举报
运行总次数:0
代码可运行

这个系列的博客贴的都是我大二的时候学习Linux系统高级编程时的一些实验程序,都挺简单的。

实验题目:Linux环境下的进程控制

实验目的:熟悉并掌握Linux环境下进程的相关函数的应用;守护进程的概念、启动和操作;进程操作程序的编写。

一、Linux进程控制

设计程序,满足如下要求:

1、设计一个程序,要求显示Linux系统分配给此程序的进程号(PID)和它的父进程号(PPID)。

在Linux环境下进程创建时,系统会分配一个唯一的数值给每个进程,这个数值就称为进程标示符(pid),他的父进程号用ppid表示。

在Linux中获取当前进程的pid、ppid可以调用getpid()和getppid()函数。

getpid函数说明如下:

所需头文件

#include<unsitd.h>

函数功能

取得当前进程的进程号

函数原型

pid_t getpid(void)

函数传入值

返回值

成功返回当前进程的标识符

所需头文件

所需头文件

#include<unistd.h>

所需头文件

函数功能

取得当前进程的父进程号

函数原型

pid_t getppid(void)

函数传入值

返回值

成功返回当前进程的父进程标识符

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1 #include<stdio.h>
2 #include<unistd.h>
3 int main()
4 {
5     printf("系统分配的进程号(PID)是:%d\n",getpid());
6     printf("系统分配的父进程号(PPID)是:%d\n",getppid());
7     return 0;
8 }

2、设计一个程序,用fork函数创建一个子进程,在子进程中给变量n赋值3,在父进程中给变量n赋值6,fork调用之后父进程和子进程的变量message和n被赋予不同的值,互不影响。

Linux下调用fork()函数可以创建一个新进程,由fork创建的新的进程被称为子进程。fork()函数调用一次返回两次,区别是子进程的返回值是0,父进程的返回值是子进程的pid。子进程是父进程的复制品,复制父进程的数据空间,堆栈等。

所需头文件

#include <unistd.h>

功能

建立一个新的进程

函数原型

pid_t fork(void)

传入值

返回值

执行成功在子进程中返回0,在父进程中返回子进程的pid,失败返回-1

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 #include<stdio.h>
 2 #include<sys/types.h>
 3 #include<stdlib.h>
 4 #include<unistd.h>
 5 int main()
 6 {
 7     pid_t pid;
 8     char *message;
 9     int n;
10     pid = fork();
11     if(pid < 0)
12     {
13         perror("fork failed!\n");
14         exit(1);
15     }
16     if(pid == 0)
17     {
18         message="This is the child!\n";
19         n=3;
20     }
21     else
22     {
23         message="This is the parent!\n";
24             n=6;
25     }
26     for(;n>0;n--)
27     {
28         printf(message);
29         sleep(1);
30     }
31 
32     return 0;
33 }

3、分别使用exec函数族中的六个函数执行命令“ifconfig eth0 192.168.110.140”。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<stdio.h>
#include<stdlib.h>
//可以分别注释掉不同的exec族函数,分别执行以查看效果。
#include<unistd.h>
#include<sys/types.h>

int main()
{
    char *const argv[]={"ifconfig","eth0","192.168.110.140",NULL};
    char *env[]={"PATH=bin:usr/sbin",NULL};
//    execl("/sbin/ifconfig","ifconfig","eth0","192.168.110.140",NULL);
//    execv("/sbin/ifconfig",argv);
//    execle("/sbin/ifconfig","ifconfig","eth0","192.168.110.140",NULL,env);
//    execve("/sbin/ifconfig",argv,env);
//    execlp("ifconfig","ifconfig","eth0","192.168.110.140",NULL);
    execvp("ifconfig",argv);
    return 0;
}

在系统中创建一个进程的目的是需要该进程完成一定的任务,需要该进程执行他的程序代码,在Linux系统中可以调用exec函数是程序执行。

系统调用exec有多种使用形式,称为exec族,他们只是在参数上不同,而功能是相同的。

在exec族里面有6个函数可以用来建立子进程,分别是execl, execcv, execle , execve, execlp, execvp,函数中第5、6个字符l, v, e, p表示函数中国的参数分别用列表传递方式,字符传递方式,可制定环境变量及路径自动搜索功能。

所需头文件

#include <unistd.h>

函数原型

int execl(const char *path,const char *arg, ...) int execv(consr char *path,char const *argv[]) int execle(consr char *path, const char *arg, ... ,char const * envp[]) int execve(consr char *path, char const *argv[],char const * envp[]) int execlp(const char *file,const char *arg, ...) int execvp(const char *file,char *const argv[] )

返回值

-1出错

而事实上,这六个函数中真正的系统调用函数只有execve(),其他的五个都是库函数,他们最终调用的都是execve这个系统函数。

exec调用举例如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1 char *const ps_argv[] = {"ps","-o", "pid,ppid",NULL};
2 char *const ps_envp[] = {"PATH = bin:/usr/bin","TERM = console",NULL};
3 
4 execl("bin/ps","ps","-o","pid,ppid",NULL);
5 execv("bin/ps",ps_argv);
6 execle("bin/ps","ps","-o","pid,ppid",NULL,ps_envp);
7 execve("bin/ps",ps_argv,ps_envp);
8 execlp("ps","ps","-o","pid,ppid",NULL);
9 execvp("ps",ps_argv);

二、僵尸进程

1、设计一个程序,要求创建一个子进程,子进程显示自己的进程号(PID)后暂停一段时间,父进程等待子进程正常结束,打印显示等待的进程号(PID)和等待的进程退出状态。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<unistd.h>
 4 #include<sys/types.h>
 5 #include<sys/wait.h>
 6 int main()
 7 {
 8     pid_t pid,wpid;
 9     int status,i;
10     pid =fork();
11     if(pid ==0)
12     {
13         printf("This is the child,进程号(PID)是:%d\n",getpid());
14         sleep(5);
15         exit(6);
16     }
17     else
18     {
19         printf("This is the parent,正在等待子进程.....\n");
20         wpid=wait(&status);
21         i=WEXITSTATUS(status);
22         printf("等待进程的进程号(PID)是:%d,结束状态:%d\n",wpid,i);
23     }
24     return 0;
25 }

2、要求子进程用sleep等待10秒,父进程用waitpid函数等待子进程正常结束,父进程在等待的时候不阻塞,每1秒在屏幕上输出一行文字,若发现子进程退出,打印等待进程的进程号(PID)和退出状态。请编写一程序进行调试。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
    pid_t pid,wpid;
    int status;
    pid=fork();
    if(pid==0)
    {
        printf("This is the child,进程号(PID)是:%d\n",getpid());
        printf("This is the child,Then slepp now!\n");
        sleep(10);
        exit(6);

    }
    else
    {
        printf("This is the parent!\n");
        while(1){
        waitpid(pid, &status, WNOHANG);
        printf("Wait for child.........\n");
        if(0 == WIFEXITED(status))
        sleep(1);
        else{
        printf("Child is end now!\n");
        printf("等待的进程的进程号(PID)是:%d,结束状态:%d\n",pid,WEXITSTATUS(status));
        break;
    }
    }
    }
}

三、守护进程

1、

编写一程序,要求运行后成为守护进程,每隔3秒修改一个本机的IP地址,并在屏幕上显示IP地址信息。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<unistd.h>
#include<sys/param.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<signal.h>
void init_daemon(void)
{
    pid_t child1,child2;
    int i;
    child1=fork();
    if(child1 >0)
        exit(0);
    else if(child1 < 0) 
    {
        perror("创建子进程失败!\n");
        exit(1);
    }
    setsid();
    chdir("/mnt/hgfs/zhaoshun");
    umask(0);
    for(i=0;i<NOFILE;++i)
        close(i);
    return;
}
int main()
{
    FILE * fp;
    char buf1[100],buf2[100];
    init_daemon();
    if((fp=fopen("ipadd","r"))=NULL)
    {
        printf("打开文件出错!\n");
    }

    while(1)

    {
        ifconfig();

        system("ifconfig");
        sleep(3);

    }

    return 0;


}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015-12-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Linux进程控制
进程是操作系统中的一个重要概念,它是一个程序的一次执行过程,程序是进程的一种静态描述,系统中运行的每一个程序都是在它的进程中运行的。
xxpcb
2020/08/04
2K0
Linux进程控制【进程程序替换】
子进程 在被创建后,共享的是 父进程 的代码,如果想实现自己的逻辑就需要再额外编写代码,为了能让 子进程 执行其他任务,可以把当前 子进程 的程序替换为目标程序,此时需要用到 Linux 进程程序替换相关知识
北 海
2023/07/01
2620
Linux进程控制【进程程序替换】
【Linux】Linux进程控制>进程创建&&进程终止&&进程等待&&进程程序替换
在linux中fork函数时非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程
用户10925563
2024/06/04
2280
【Linux】Linux进程控制>进程创建&&进程终止&&进程等待&&进程程序替换
Linux系统-进程控制
Linux进程控制 零、前言 一、进程创建 1、fork函数 2、fork返回值 写时拷贝 3、fork用法 4、fork失败 二、进程终止 1、退出码 2、退出方法 1) 调用_exit函数 2)调用exit函数 3)main函数return 4)异常退出 3、理解终止 三、进程等待 1、等待方法 2、获取status 3、理解等待 四、进程替换 1、替换原理 2、替换方法 五、实现简易shell 零、前言 前篇我们讲解学习了关于进程的概念知识,本章主要讲解关于进程的控制,深入学习进程 一、进程创建
用户9645905
2022/11/30
1.5K0
Linux系统-进程控制
8(进程控制)
本章需要熟练掌握如下几个函数fork,exec族,_exit,wait,waitpid
提莫队长
2019/02/21
4960
Linux之进程控制
此外还可以通过调用fork函数创建子进程,子进程和父进程共享fork之后的代码,可以采用对fork返回值进行判断的办法来让父子进程分别执行后续代码的一部分。
始终学不会
2023/04/17
8350
Linux之进程控制
【Linux系统编程】八、进程程序替换
​ 将磁盘中指定的程序加载到内存中,让指定的进程进行执行。不论是哪种后端语言写的程序,exec* 类的函数都可以调用。
利刃大大
2025/02/23
520
【Linux系统编程】八、进程程序替换
【Linux】进程控制
在 Linux 中 fork 函数是非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。我们在前面的学习中也遇到过,所以在此简单介绍一下。
YoungMLet
2024/03/01
1650
【Linux】进程控制
Linux进程控制
在进程概念这篇文章中,我们浅浅地了解了一下fork函数,它的功能是让父进程去创建一个子进程,并且有两个返回值,对应着父进程的返回值和子进程的返回值。那么,为什么会这样?接下来我们好好地讨论一下fork函数。
二肥是只大懒蓝猫
2023/03/30
2.4K0
Linux进程控制
温故Linux后端编程(二):进程
fork调用一次返回两次 父进程中返回子进程id (就是大于0的意思) 子进程返回0 读时共享写时复制,可保高效
看、未来
2021/09/18
7200
进程控制
在linux中fork函数是非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。
海盗船长
2020/08/27
7330
【Linux】万字解读<进程控制>:创建&中止&等待&替换
YY的秘密代码小屋
2024/09/11
1150
【Linux】万字解读<进程控制>:创建&中止&等待&替换
详谈 Linux进程控制(看这一篇就够了)
本文将系统介绍进程控制的基本要素,包括进程创建, 进程终止, 进程等待, 进程替换等方面。深入理解进程创建的相关知识, 帮助更好的构建知识架构!
用户11317877
2024/12/20
1370
详谈 Linux进程控制(看这一篇就够了)
【Linux】从 fork() 到 exec():理解 Linux 进程程序替换的魔法
进程程序替换是指一个进程用另一个新的可执行程序来替换当前正在执行的程序,这个过程通过通过exec系列函数完成。在Linux或UNIX系统中,进程程序替换通常发生在一个进程通过fork()创建了子进程之后,子进程用exec()函数加载和执行另一个程序。 也就是说,进程程序替换就是在不改变进程的PID(进程ID)的情况下,用一个全新的程序来替换当前的内存空间和执行内容。 当程序调用一种exec函数时,该进程的用户空间代码和数据完全被新的程序替换,从新程序的启动例程开始执行。
Yui_
2024/10/21
1150
【Linux】从 fork() 到 exec():理解 Linux 进程程序替换的魔法
【linux】进程等待与进程替换
任何子进程,在退出的情况下,一般必须要被父进程进行等待。进程在退出的时候,如果父进程不管不顾,退出进程,状态Z(僵尸状态),内存泄漏
用户11029103
2024/11/16
950
【linux】进程等待与进程替换
Linux系统下进程编程之exec族函数解析(四)
fork函数是用于创建一个子进程,该子进程几乎是父进程的副本,而有时我们希望子进程去执行另外的程序,exec函数族就提供了一个在进程中启动另一个程序执行的方法。它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段,在执行完之后,原调用进程的内容除了进程号外,其他全部被新程序的内容替换了。另外,这里的可执行文件既可以是二进制文件,也可以是Linux下任何可执行脚本文件。
用户6280468
2022/03/18
1.4K0
Linux系统下进程编程之exec族函数解析(四)
【Linux篇】进程控制
在linux中fork函数是非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。
_孙同学
2025/03/21
660
【Linux篇】进程控制
【Linux】进程的程序替换
红框中的代码实际上是父进程的代码,在没有执行fork之前代码就有了,在没有创建子进程之前,父进程的代码加载到内存了,子进程被创建出来是没有独立的代码,这个代码是父进程的代码,父进程通过if判断分流让子进程去跑了
lovevivi
2023/04/28
2K0
【Linux】进程的程序替换
【Linux进程控制】五、wait()函数——子进程回收
僵尸进程:子进程结束,父进程没有回收子进程的资源(PCB),这个资源必须要由父进程回收,否则就形成僵尸进程。
mindtechnist
2024/08/08
1140
【Linux进程控制】五、wait()函数——子进程回收
Linux:进程控制(二.详细讲解进程程序替换)
进程程序替换是指在运行过程中将一个进程的地址空间中的代码、数据和堆栈等内容完全替换为另一个程序的代码、数据和堆栈的过程。这个过程通常是由操作系统提供的 exec 系列函数来实现的:
是Nero哦
2024/05/30
2300
Linux:进程控制(二.详细讲解进程程序替换)
相关推荐
Linux进程控制
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验