linux c编程 进程编程(整理)

(代码来自《嵌入式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命令:在指定时刻执行指定的命令序列

格式:

at [-V] [-q x] [-f file] [-m] time

atq [-V] [-q x]

atrm [-V] [-q x] job…

batch [-V] [-f file] [-m]

  • bg命令:使一个被挂起的进程在后台执行

格式:bg 该命令无参数。

先使用组合键"Ctrl+Z"。然后使用bg命令。如果想直接把这个命令放在后台执行,可以在命令后使用"&"符号:

#du -a / | sort -rn > /tmp/du.sorted &

  • fg命令:使一个被挂起的进程在前台执行

格式:fg -[job-spec]

  • jobs命令:显示后台任务的执行情况

格式:jobs [选项] [jobspec…]

  • kill命令:终止一个进程

格式:kill [-s signal |-p] [-a]pid

  • crontab命令:用于安装、删除或者列出用于驱动cron后台进程的任务表。然后,该配置由cron守护进程在设定的时间执行

格式:crontab [-u user] 文件

  • ps命令:查看系统中进程的状态

格式:ps [选项],如ps aux

  • pstree命令:列出当前的进程,以及它们的树状结构

格式:pstree [选项] [pid|user]

  • top命令:显示系统当前的进程状况

格式:top [选项]

说明:top命令和ps命令的基本作用是相同的,都显示系统当前的进程状况。但是top是一个动态显示过程,即可以通过用户按键来不断刷新当前状态。

  • nice命令:改变程序执行的优先权等级

格式:nice [-n <优先等级>][--help][--version][命令]

说明:应用程序优先权值的范围从-20~19,数字越小,优先权就越高。一般情况下,普通应用程序的优先权值(CPU使用权值)都是0,如果让常用程序拥有较高的优先权等级,自然启动和运行速度都会快些。需要注意的是普通用户只能在0~19之间调整应用程序的优先权值,只有超级用户有权调整更高的优先权值(从-20~19)。

  • renice命令:允许用户修改一个正在运行的进程的优先权

格式:renice priority [ [ -p ] pids ] [ [ -g ] pgrps ] [ [ -u ] users ]

说明:renice命令可重新调整正在执行的程序的优先权等级。默认是以程序识别码指定程序,调整其优先权,也可以指定程序群组或用户名称调整优先权等级,并修改所有隶属于该程序群组或用户的程序的优先权。等级范围从-20~19,只有超级用户可以改变其他用户程序的优先权和设置负数等级。普通用户只能对自己所有的进程使用renice命令。

  • sleep命令:使进程暂停执行一段时间

格式:sleep number [选项]

  • nohup命令:用户退出系统之后继续工作

格式:nohup命令

说明:一般退出Linux系统时,会把所有的程序全部结束掉,包括那些后台程序。但有时候,例如,用户正在下载一个很大的文件,但是你因下班或有事需要先退出系统,希望退出系统时程序还能继续执行。这时,我们就可以使用nohup命令使进程在用户退出后仍继续执行。同时这些进程都在后台执行(命令放到后台运行,nohup必须与&操作同时使用),结果则会写到用户自己的目录下的nohup.out文件里。

  • pgrep命令:查找当前运行的进程,并列出匹配给定条件的进程的pid,所有的条件都必须匹配才会被列出

格式:pgrep [选项][程序名]

  • chkconfig命令: 检查,设置系统的各种服务

格式: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)
功能:创建子进程

fork会被调用一次,却返回两次,有三种不同的返回值:
1.在父进程中,fork返回子进程创建的PID.
2.在子进程中,fork返回0.
3.如果出现错误,fork返回一个负值.
注:子进程会复制代码自行运行,子进程中的变量不影响父进程,子进程执行的次序不确定.

pid_t vfork(void)
功能:创建子进程
vfork会被调用一次,却返回两次,有三种不同的返回值:
1.在父进程中,vfork返回子进程创建的PID.
2.在子进程中,vfork返回0.
3.如果出现错误,vfork返回一个负值.
注:子进程与父进程共享数据段,子进程中的变量与父进程保持一致,子进程比父进程优先运行.



进程函数-exec函数
注:exec函数启动一个新的程序,会替换原有的进程,因此进程的PID保持不变.
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才返回.


守护进程
五步走+出错处理
1,创建子进程,父进程退出
2,setsid()
3,切换目录
4,umask
5,释放文件资源

出错处理syslog   openlog closelog

第三部份:进程编程实例


多进程实例

/* 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);
  		}	
  	}
}




你可能感兴趣的:(linux c编程 进程编程(整理))