专栏首页游戏开发那些事【Linux程序设计】之进程控制&守护进程

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

这个系列的博客贴的都是我大二的时候学习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)

函数传入值

返回值

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

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

 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”。

#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调用举例如下:

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)和等待的进程退出状态。

 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)和退出状态。请编写一程序进行调试。

#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地址信息。

#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;


}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【Unity游戏开发】记一次解决 LuaFunction has been disposed 的bug的过程

      RT,本篇博客记录的是马三的一次解决 LuaFunction has been disposed 的bug的全过程,事情还要从马三的自研框架 ColaFra...

    马三小伙儿
  • 【游戏开发】网络编程之浅谈TCP粘包、拆包问题及其解决方案

    现如今手游开发中网络编程是必不可少的重要一环,如果使用的是TCP协议的话,那么不可避免的就会遇见TCP粘包和拆包的问题,马三觉得haifeiWu博主的 TCP ...

    马三小伙儿
  • 【python游戏编程之旅】第四篇---pygame中加载位图与常用的数学函数。

    本系列博客介绍以python+pygame库进行小游戏的开发。有写的不对之处还望各位海涵。

    马三小伙儿
  • 100个 Linux 命令(8)-统计和查看系统状态

    pstree命令以树的形式显示进程信息,默认树的分支是收拢的,也不显示pid,要显示这些信息需要指定对应的选项。

    懒人的小脑
  • Linux进程及作业管理

    版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/gon...

    魏晓蕾
  • 操作系统学习笔记-3:初识进程和进程控制

    在 操作系统学习笔记-1:基础概念) 中,我们介绍了与操作系统相关的一些概念,在 操作系统学习笔记-2:体系结构设计和运行机制) 中,我们又介绍了操作系统的结构...

    Chor
  • Python的进程

    进程 说明:本文是基于Py2.X环境, Python实现多进程的方式主要有两种:一种方法是使用os模块中的fork方法; 另一种是使用multiprocessi...

    企鹅号小编
  • 初遇python进程

      cpu     中央处理器:计算(数字计算和逻辑计算)和控制(控制所有硬件协调工作)

    py3study
  • Android 中进程的级别以及 Service 的优先级

    总结: 我们已经知道有这 5 个进程了,并且他们的优先级都列出来的,这样我们就可以根据优先级来让我们的 APP 尽量不被杀死了。

    开发者
  • 1.并发编程多进程(理论部分)

    ​ 太白金星在一个时间段内有很多任务要做:python备课的任务,写书的任务,交女朋友的任务,王者荣耀上分的任务,  

    changxin7

扫码关注云+社区

领取腾讯云代金券