(代码来自《嵌入式linux应用程序开发标准教程》)
概览:
第一部份:进程简介
第二部份:进程控制 :命令 函数
第三部份:进程实例: 多进程 守护进程
第四部份:附加材料
linux 进程控制函数大全
http://operatingfocus.bokee.com/3327857.html
http://blog.sina.com.cn/s/blog_487df383010009rd.html
进程控制函数简介 http://heould.diandian.com/post/2011-11-16/40027176869
fork函数详解http://z515256164.blog.163.com/blog/static/3244302920122149358550/
第一部份:进程简介
进程是Linux系统的基本调度和管理资源的单位,它是通过进程控制块来描述的。进程控制块包含了进程的描述信息、控制信息以及资源信息,它是进程的一个静态描述。在Linux中,进程控制块中的每一项都是一个task_struct结构。
在Linux中最主要的进程标识有进程号(PID,Process Idenity Number)和它的父进程号(PPID,parent process ID)。其中PID惟一地标识一个进程。PID和PPID都是非零的正整数。
在Linux中获得当前进程的PID和PPID的系统调用函数为getpid()和getppid(),通常程序获得当前进程的PID和PPID之后,可以将其写入日志文件以做备份。
另外,进程标识还有用户和用户组标识、进程时间、资源利用情况等
进程是Linux系统的基本调度和管理资源的单位,它是通过进程控制块来描述的。进程控制块包含了进程的描述信息、控制信息以及资源信息,它是进程的一个静态描述。在Linux中,进程控制块中的每一项都是一个task_struct结构。
在Linux中最主要的进程标识有进程号(PID,Process Idenity Number)和它的父进程号(PPID,parent process ID)。其中PID惟一地标识一个进程。PID和PPID都是非零的正整数。
在Linux中获得当前进程的PID和PPID的系统调用函数为getpid()和getppid(),通常程序获得当前进程的PID和PPID之后,可以将其写入日志文件以做备份。
另外,进程标识还有用户和用户组标识、进程时间、资源利用情况等
进程三种状态 就绪 执行 等待
第二部份:进程控制
常用命令
http://www.cnblogs.com/sujz/articles/2044456.html
格式:
at [-V] [-q x] [-f file] [-m] time
atq [-V] [-q x]
atrm [-V] [-q x] job…
batch [-V] [-f file] [-m]
格式:bg 该命令无参数。
先使用组合键"Ctrl+Z"。然后使用bg命令。如果想直接把这个命令放在后台执行,可以在命令后使用"&"符号:
#du -a / | sort -rn > /tmp/du.sorted &
格式:fg -[job-spec]
格式:jobs [选项] [jobspec…]
格式:kill [-s signal |-p] [-a]pid
格式:crontab [-u user] 文件
格式:ps [选项],如ps aux
格式:pstree [选项] [pid|user]
格式:top [选项]
说明:top命令和ps命令的基本作用是相同的,都显示系统当前的进程状况。但是top是一个动态显示过程,即可以通过用户按键来不断刷新当前状态。
格式:nice [-n <优先等级>][--help][--version][命令]
说明:应用程序优先权值的范围从-20~19,数字越小,优先权就越高。一般情况下,普通应用程序的优先权值(CPU使用权值)都是0,如果让常用程序拥有较高的优先权等级,自然启动和运行速度都会快些。需要注意的是普通用户只能在0~19之间调整应用程序的优先权值,只有超级用户有权调整更高的优先权值(从-20~19)。
格式:renice priority [ [ -p ] pids ] [ [ -g ] pgrps ] [ [ -u ] users ]
说明:renice命令可重新调整正在执行的程序的优先权等级。默认是以程序识别码指定程序,调整其优先权,也可以指定程序群组或用户名称调整优先权等级,并修改所有隶属于该程序群组或用户的程序的优先权。等级范围从-20~19,只有超级用户可以改变其他用户程序的优先权和设置负数等级。普通用户只能对自己所有的进程使用renice命令。
格式:sleep number [选项]
格式:nohup命令
说明:一般退出Linux系统时,会把所有的程序全部结束掉,包括那些后台程序。但有时候,例如,用户正在下载一个很大的文件,但是你因下班或有事需要先退出系统,希望退出系统时程序还能继续执行。这时,我们就可以使用nohup命令使进程在用户退出后仍继续执行。同时这些进程都在后台执行(命令放到后台运行,nohup必须与&操作同时使用),结果则会写到用户自己的目录下的nohup.out文件里。
格式:pgrep [选项][程序名]
格式:chkconfig [--add][--del][--list][系统服务]
获取进程id
http://blog.csdn.net/jpcfei/article/details/6288467
Linux进程的管理 <一>获取进程信息函数
进程又称任务,是一个动态的使用系统资源、处于活动状态的应用程序。
进程的管理由进程控制块PCB、进程调度、中断管理、任务队列等组成,它是linux文件系统、存储管理、设备管理和驱动程序的基础。
进程控制块PCB中包含了进程的所有信息,主要包括进程PID、进程所占有的内存区域、文件描述符和进程环境等信息。
他用task_struct的数据结构表示,存在于include/linux/sch.h
进程状态及转换
#define TASK_RUNNING 0 //运行状态
#define TASK_INTERRUPTIBLE 1 //等待状态(可被中断)
#define TASK_UNINTERRUPTIBLE 2 //等待状态(不可被中断)
#define TASK_STOPPED 4 //停止状态
#define TASK_ZOMBIE 8 //睡眠状态
#define TASK_DEAD 16 //僵死状态
进程的基本操作,六大类:
1.获取进程信息函数:主要通过读取进程控制块PCB中的信息。
(1)getpid()
功能:用来获取目前进程的进程标识。
定义函数:pid_t getpid(void)
返回值:返回当前进程的进程识别号。
头文件:#include <unistd.h>
(2)getppid()
功能:用来获取目前进程的父进程标识。
定义函数:pid_t getppid(void)
返回值:返回当前进程的父进程识别号。
头文件:#include <unistd.h>
(3)getpgid()
功能:用来获得参数pid指令进程所属于的组识别号,若参数为0,则返回当前进程的组识别码。
定义函数:pid_t getpgid(pid_t pid)
返回值:执行成功则返回正确的组识别码,若有错则返-1,错误原因存在于errno中。
头文件:#include <unistd.h>
(4)getpgrp()
功能:用来获得目前进程所属于的组识别号,等价于getpgid(0)。
定义函数:pid_t getpgrp(void)
返回值:执行成功则返回正确的组识别码。
头文件:#include <unistd.h>
(5)getpriotity(void)
功能:用来获得进程,进程组和用户的进程执行优先权。
定义函数:int getpriority(int which,int who)
参数含义:
which:
PRIO_PROCESS who为进程的识别码
PRIO_PGRP who为进程的组识别码
PRIO_USER who为用户识别码
返回值:执行成功则返回当前进程的优先级(-20--20),值越小优先级越高。若出错则返-1,原因在errno中。
头文件:#include <sys/resource.h>
简单实例:
[keven@localhost systemCall]$ cat -n get_process_information.c
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <sys/resource.h>
4
5 int main(/*int argc,char **argv*/)
6 {
7 printf("This process's pid is:%d",getpid());
8 printf("/nThis process's farther pid is:%d",getppid());
9 printf("/nThis process's group pid is:%d",getpgid(getpid()));
10 printf("/nThis process's group pid is:%d",getpgrp());
11 printf("/nThis process's priority is:%d/n",getpriority(PRIO_PROCESS,getpid()));
12 return 0;
13 }
[keven@localhost systemCall]$ ./get_process_information
This process's pid is:6172
This process's farther pid is:5681
This process's group pid is:6172
This process's group pid is:6172
This process's priority is:0
[keven@localhost systemCall]$
进程控制函数
http://yayi.me/doc/Process-Function.html
进程函数-获取进程ID
pid_t getpid(void)功能:获取本进程ID
pid_t getppid(void)功能:获取父进程ID
pid_t fork(void)功能:创建子进程
pid_t vfork(void)功能:创建子进程
int execl(const char * path , const char * arg1 , ...)
变量 | 作用 |
---|---|
path | 被执行程序名(含完整路径) |
arg1 - argn | 被执行程序所需的命令行参数,含程序名.以空指针(NULL)结束. |
int execlp(const char * path , const char * arg1 , ...)
变量 | 作用 |
---|---|
path | 被执行的程序名(不含路径,将从PATH环境变量中查找该程序) |
arg1 - argn | 被执行程序所需的命令行参数,含程序名.以空指针(NULL)结束. |
int execv(const char * path , char * const argv[])
变量 | 作用 |
---|---|
path | 被执行程序名(含完整路径) |
argv[ ] | 被执行程序所需要的命令行参数数组. |
int system(const char* string)功能:调用fork产生子进程,由子进程调用"/bin/sh -c string"來执行参数string所代表的命令与参数.
pid_t wait(int * status)功能:阻塞该进程,直到其某个子进程退出.
int pause(void)功能:pause只有在执行了一个信号处理程序并从其返回时,pause才返回.
第三部份:进程编程实例
多进程实例
/* multi_proc.c */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include <sys/wait.h> int main(void) { pid_t child1, child2, child; /*ŽŽœšÁœžö×Óœø³Ì*/ child1 = fork(); /*×Óœø³Ì1µÄ³öŽíŽŠÀí*/ if (child1 == -1) { printf("Child1 fork error\n"); exit(1); } else if (child1 == 0) /*ÔÚ×Óœø³Ì1Öе÷ÓÃexeclpº¯Êý*/ { printf("In child1: execute 'ls -l'\n"); if (execlp("ls", "ls", "-l", NULL) < 0) { printf("Child1 execlp error\n"); } } else /*ÔÚžžœø³ÌÖеȎý×Óœø³Ì2µÄÍ˳ö*/ { child2 = fork(); if (child2 == -1) /*×Óœø³Ì2µÄ³öŽíŽŠÀí*/ { printf("Child2 fork error\n"); exit(1); } else if( child2 == 0 ) /*ÔÚ×Óœø³Ì2ÖÐʹÆäÔÝÍ£5s*/ { printf("In child2: sleep for 5 seconds and then exit\n"); sleep(5); exit(0); } printf("In father process:\n"); child = waitpid(child1, NULL, 0); if (child == child1) { printf("Get child1 exit code\n"); } else { printf("Error occured!\n"); } do { child = waitpid(child2, NULL, WNOHANG ); if (child == 0) { printf("The child2 process has not exited!\n"); sleep(1); } } while (child == 0); if (child == child2) { printf("Get child2 exit code\n"); } else { printf("Error occured!\n"); } } exit(0); }
守护进程实例
/* daemon_proc.c */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include <sys/wait.h> #include <syslog.h> int main(void) { pid_t child1,child2; int i; /*创建子进程1*/ child1 = fork(); if (child1 == 1) { perror("child1 fork"); exit(1); } else if (child1 > 0) { exit(0); } /*打开日志服务*/ openlog("daemon_proc_info", LOG_PID, LOG_DAEMON); /*以下几步是编写守护进程的常规步骤*/ setsid(); chdir("/"); umask(0); for(i = 0; i < getdtablesize(); i++) { close(i); } /*创建子进程2*/ child2 = fork(); if (child2 == 1) { perror("child2 fork"); exit(1); } else if (child2 == 0) { /*在日志中写入字符串*/ syslog(LOG_INFO, " child2 will sleep for 10s "); sleep(10); syslog(LOG_INFO, " child2 is going to exit! "); exit(0); } else { waitpid(child2, NULL, 0); syslog(LOG_INFO, " child1 noticed that child2 has exited "); /*关闭日志服务*/ closelog(); while(1) { sleep(10); } } }