【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) | |
| 函数传入值 | 无 | |
| 返回值 | 成功返回当前进程的父进程标识符 |
#include<stdio.h>
#include<unistd.h>
int main()
{
printf("系统分配的进程号(PID)是:%d\n",getpid());
printf("系统分配的父进程号(PPID)是:%d\n",getppid());
return ;
}
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 |
#include<stdio.h>
#include<sys/types.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
pid_t pid;
char *message;
int n;
pid = fork();
if(pid < )
{
perror("fork failed!\n");
exit();
}
if(pid == )
{
message="This is the child!\n";
n=;
}
else
{
message="This is the parent!\n";
n=;
}
for(;n>;n--)
{
printf(message);
sleep();
} return ;
}
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 ;
}
在系统中创建一个进程的目的是需要该进程完成一定的任务,需要该进程执行他的程序代码,在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调用举例如下:
char *const ps_argv[] = {"ps","-o", "pid,ppid",NULL};
char *const ps_envp[] = {"PATH = bin:/usr/bin","TERM = console",NULL};
execl("bin/ps","ps","-o","pid,ppid",NULL);
execv("bin/ps",ps_argv);
execle("bin/ps","ps","-o","pid,ppid",NULL,ps_envp);
execve("bin/ps",ps_argv,ps_envp);
execlp("ps","ps","-o","pid,ppid",NULL);
execvp("ps",ps_argv);
二、僵尸进程
1、设计一个程序,要求创建一个子进程,子进程显示自己的进程号(PID)后暂停一段时间,父进程等待子进程正常结束,打印显示等待的进程号(PID)和等待的进程退出状态。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
int main()
{
pid_t pid,wpid;
int status,i;
pid =fork();
if(pid ==)
{
printf("This is the child,进程号(PID)是:%d\n",getpid());
sleep();
exit();
}
else
{
printf("This is the parent,正在等待子进程.....\n");
wpid=wait(&status);
i=WEXITSTATUS(status);
printf("等待进程的进程号(PID)是:%d,结束状态:%d\n",wpid,i);
}
return ;
}
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==)
{
printf("This is the child,进程号(PID)是:%d\n",getpid());
printf("This is the child,Then slepp now!\n");
sleep();
exit(); }
else
{
printf("This is the parent!\n");
while(){
waitpid(pid, &status, WNOHANG);
printf("Wait for child.........\n");
if( == WIFEXITED(status))
sleep();
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 >)
exit();
else if(child1 < )
{
perror("创建子进程失败!\n");
exit();
}
setsid();
chdir("/mnt/hgfs/zhaoshun");
umask();
for(i=;i<NOFILE;++i)
close(i);
return;
}
int main()
{
FILE * fp;
char buf1[],buf2[];
init_daemon();
if((fp=fopen("ipadd","r"))=NULL)
{
printf("打开文件出错!\n");
} while() {
ifconfig(); system("ifconfig");
sleep(); } return ; }
【Linux程序设计】之进程控制&守护进程的更多相关文章
- Linux中的两种守护进程stand alone和xinetd
Linux中的两种守护进程stand alone和xinetd --http://www.cnblogs.com/itech/archive/2010/12/27/1914846.html#top 一 ...
- Linux进程学习(孤儿进程和守护进程)
孤儿进程和守护进程 通过前面的学习我们了解了如何通过fork()函数和vfork()函数来创建一个进程.现在 我们继续深入来学习两个特殊的进程:孤儿进程和守护进程 一.孤儿进程 1.什么是 孤儿进程如 ...
- Linux进程学习 - 孤儿进程和守护进程
孤儿进程和守护进程 通过前面的学习我们了解了如何通过fork()函数和vfork()函数来创建一个进程.现在 我们继续深入来学习两个特殊的进程:孤儿进程和守护进程 一.孤儿进程 1.什么是 孤儿进程如 ...
- Linux 普通进程 后台进程 守护进程
一.普通进程与后台进程 默认情况下,进程是在前台运行的,这时就把shell给占据了,我们无法进行其它操作.对于那些没有交互的进程,很多时候,我们希望将其在后台启动,可以在启动参数的时候加一个'& ...
- linux usb枚举过程分析之守护进程及其唤醒【转】
转自:http://blog.csdn.net/xuelin273/article/details/38646765 usb热插拔,即usb设备可以实现即插即用,像U盘一样,插到电脑里就可以用,不用时 ...
- Linux 普通进程 后台进程 守护进程(转)
一.普通进程与后台进程 默认情况下,进程是在前台运行的,这时就把shell给占据了,我们无法进行其它操作.对于那些没有交互的进程,很多时候,我们希望将其在后台启动,可以在启动参数的时候加一个'& ...
- Windows 和 Linux 上Redis的安装守护进程配置
# Windows 和 Linux 上Redis的安装守护进程配置 Redis 简介 Redis是目前最常用的非关系型数据库(NOSql)之一,常以Key-Value的形式存储.Redis读写速度 ...
- Linux守护进程列表/守护进程
在linux或者unix操作系统中在系统引导的时候会开启很多服务,这些服务就叫做守护进程.为了增加灵活性,root可以选择系统开启的模式,这些模式叫做运行级别,每一种运行级别以一定的方式配置系统. ...
- 【Linux 进程】孤儿进程、僵尸进程和守护进程
1.孤儿进程: 孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程.孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作.孤儿进程是 ...
随机推荐
- Java ANT build.xml
详情请参考:http://www.cnblogs.com/xionghui/archive/2012/03/13/2393679.html
- NYOJ之XX和OO
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAskAAAI0CAIAAABgWyN9AAAgAElEQVR4nO3dPW7jyt4n4NmEcy/EaW
- Redis笔记(五)Redis的事务
>>关系型数据库的事务 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消. Atomic(原子性): 一个事务(transaction)中的 ...
- 手机的ROM,RAM是各自存放什么?所谓“运行内存”和“机身内存”究竟有什么区别?
手机的内存分为运行内存(RAM)和非运行内存(也叫机身内存.储存空间.ROM) 1.手机的内存,分为存储内存和运行内存,相当于电脑的硬盘和内存条.2.存储内存分为机身内存和存储卡.3.rom是存储内存 ...
- OCJP(1Z0-851) 模拟题分析(七)-->214
Exam : 1Z0-851 Java Standard Edition 6 Programmer Certified Professional Exam 以下分析全都是我自己分析或者参考网上的,定有 ...
- JavaScript中判断对象类型方法大全2
在JavaScript中,有5种基本数据类型和1种复杂数据类型,基本数据类型有:Undefined, Null, Boolean, Number和String:复杂数据类型是Object,Object ...
- JavaScript是如何实现继承的(六种方式)
大多OO语言都支持两种继承方式: 接口继承和实现继承 ,而ECMAScript中无法实现接口继承,ECMAScript只支持实现继承,而且其实现继承主要是依靠原型链来实现,下文给大家技术js实现继承的 ...
- AIX扩展文件系统的大小
由于AIX系统空间不够需要增加硬盘,希望增加文件系统的空间,折腾了好几天怎么都不能扩展文件系统的空间,原来是把硬盘加错了卷组 首先,确定文件系统所在的LV /dev/datalv 270.0 ...
- SSIS 包单元测试检查列表
1. 使用脚本任务(Script tasks) 组建的时候,在日志里增加一些调试信息,例如变量更新信息,可以帮助我们从日志中查看到变量是在何时何地更新的. 2. 使用ForceExecutionRes ...
- Freemarker使用入门
一.概述: FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写 Template + data_model = output FreeMarker也是与Web容 ...