新闻  |   论坛  |   博客  |   在线研讨会
进程控制开发
mayer | 2009-05-22 18:43:39    阅读:1602   发布文章

进程控制开发

 

掌握进程相关的基本概念

程序是一个静态的概念,进程是一个动态的概念,是程序执行的过程。

Linux最主要的标识有进程号(PID)和它的父进程号(PPID),获得PID和PPID的函数分别为getpid和getppid。

进程可以分为执行态、就绪态、等待态。

 

掌握linux下的进程结构

linux下的进程分为数据段、代码段和堆栈段,其中,数据段用来存放数据、全局变量及动态分配的空间等。代码段用来存放代码。堆栈段用来存放局部变量跟子程序返回地址及子程序的参数。

 

掌握linux下的进程创建及进程管理

linux进程管理包括启动进程和调度进程。

启动进程包括手动启动跟调度启动。

调度进程: ps、top、nice、renice、kill、crontab、bg 等函数。 

进程创建函数

1、fork()

有两个返回值

返回0,    当前进程是子进程   (就是子进程的返回值为0)

返回大于0,当前进程是父进程,返回的值就是子进程的ID。(父进程的返回值为子进程ID)

返回-1,     出错。

用fork函数得到的子进程是父进程的一个复制品,得到父进程的大部分内容。子进程把所独有的只有它的进程号、资源使用和定时器等。由于复制了父进程的数据段、代码段、堆栈段等大部分内容,所以fork的执行速度并不快。

Fork使用:

Result=fork();

If(result==-1) //出错

{

   perror(“fork error!”);

   exit(1);

}

else if(result==0) //子进程

{

  printf(“child process!”);

}

else //result>0 父进程

{

  printf(“father process!”);

}

 

2、exec系列函数

创建进程后的进程执行函数

提供了一个在进程中启动另一个程序执行的方法。

本系列共有6个函数

execl(const char *path,const char *arg…)

execv(const char *path,const char *argv[])

execle(const char *path,const char *arg,…,const char *envp[])

execve(const char *path,const char *argv[],const char *envp[])

execlp(const char *file,const char *arg…)

execvp(const char *file,const char *argv[])

返回为-1,出错

其中,前四个exec为公共,

第五个字母若为”l”,表示是逐个列举方式(list),语法char *arg,若为”v”,则表示是所有参数整体构造指针数组传递(vertor),语法 char *argv[]。

第六个字母若为”e”,可以指定当前进程的环境变量。语法char *const envp[]. 若为p,表示文件查找方式可以给出文件名。系统会自己从环境变量中查找。

使用示例:

execl:

execl(“/bin/ps”,”ps”,”-ef”,NULL)

execv:

char *argv[]={“env”,NULL};

execv(“/bin/env”,argv);

 

execle:

char *envp[]={"PATH=/tmp","USR=sunq",NULL};

if(execle("/bin/ps","ps","-ef",NULL,envp)<0)         

 

execve:

char *argv[]={"ps","-ef",NULL};

char *envp[]={"PATH=/tmp","USR=sunq",NULL};

if(execve("/bin/ps",argv,envp)<0)             //execve

 

execlp

if(execlp("ps","ps","-ef",NULL)<0)      //execlp

 

execvp

char *argv[]={"ps","-ef",NULL};

if(execvp("ps",argv)<0)                 //execvp

 

1、 exit和_exit

exit退出时做处理

_exit退出时直接退出

 

僵尸进程的概念,请参考僵尸进程详解   僵尸进程详解1

当一个子进程结束后,父进程若还在,则会子进程将会产生僵尸进程。

结束僵尸进程的方法:1、通过wait、waitpid函数来进行。 2、结束父进程,init会自动收尸。

2、  wait waitpid

wait使父进程阻塞,直到子进程结束或者接到一个指定信号。否则一直阻塞。

Waitpid 跟wait作用一样,不过提供更多选项,不一定阻塞,有若干选项。

Wait实例

pc=fork();

if(pc==0)

{

sleep(5);

exit(0);

}

else if(pc>0)

{

printf("child is sleep!\n");

wait(NULL);  //等待子进程退出

printf("child is exited!\n");

}

 

waitpid

pc=fork();

if(pc==0)

{

sleep(5);

exit(0);

}

else if(pc>0)

{

printf("child is sleep!\n");

waitpid(pc,NULL,0);  //等待子进程退出

printf("child is exited!\n");

}

 

 

掌握linux下进程创建相关的系统调用

 

掌握守护进程的概念

守护进程是通常所说的daemon进程,是linux的后台服务进程,通常独立于控制终端周期性执行或者等待某种事物。

如果不想让一个进程不因为用户或者终端或者其它所改变而改变,则必须设置为守护进程。

 

掌握守护进程的启动方法

 

掌握守护进程的输出及建立方法

建立一个守护进程的步骤:

1、  建立子进程、父进程退出

pc=fork(); //建立子进程

if(pc>0)  //退出父进程

exit(0);

 

2、  建立新会话

由于用fork建立子进程时大多复制的父进程的内容,所以

需完成以下任务:

脱离原终端控制

脱离原进程组的控制

脱离原会话组的控制

脱离函数:setsid

成功返回进程组ID,失败返回-1

   isetsid();

 

 

3、  改变当前目录为根目录

因为在工作的时候目录所在的文件系统是不能被卸载的。例:如果当前守护进程工作在/mnt/usb中,那么如果现在想卸载/mnt/usb,则会出现无法卸载的情况。所以,把目录定位到根目录下则不会出现这种情况。除非有人想卸载根目录^_^。

函数:chdir

chdir();

                 

4、  重设文件权限掩码

umask(0);

 

5、  关闭文件描述符

for(i=0;I<MAXFILE,I++)

close(i);

 

守护进程的出错处理

为了解决守护进程无法调试的问题,所以可以把出错信息发送到系统的日志文件中。

方法:使用守护进程syslogd来维护的syslog服务,向日志文件/var/log/messages中输出相关信息来完成调试(注:在/etc/syslog.conf中可以配置不同的消息发向何处)。

该机制提供了三个syslog函数:openlog,syslog,closelog.

Openlog

void openlog( char *ident, int option, int  facility) 

打开系统日志服务的一个连接

option 
       用於openlog()的option参数可以是以下几个的组合: 

LOG_CONS : 如果送到system logger时发生问题,直接写入系统console。 

LOG_NDELAY : 立即开启连接(通常,连接是在第一次写入讯息时才打开的)。 

LOG_PERROR :  将讯息也同时送到stderr 
       LOG_PID :  将PID含入所有讯息中 

facility 
       facility参数用来指定何种程式在记录讯息,这可让设定档来设定何种讯息如何处理。 
       LOG_AUTH : 安全/授权讯息(别用这个,请改用LOG_AUTHPRIV) 
       LOG_AUTHPRIV : 安全/授权讯息 
       LOG_CRON : 时间守护进程专用(cron及at) 
       LOG_DAEMON : 其它系统守护进程
       LOG_KERN : 核心讯息 
       LOG_LOCAL0到LOG_LOCAL7 : 保留 
       LOG_LPR : 行打印机子系统 
       LOG_MAIL : mail邮件子系统 
       LOG_NEWS : USENET 新闻子系统 
       LOG_SYSLOG : syslogd内部所产生的讯息 
       LOG_USER(default) : 一般使用者等级讯息 
       LOG_UUCP : UUCP子系统 

syslog

void syslog( int priority, char *format, ...) 

向日志文件中写入消息

priority
       决定讯息的重要性.  以下的等级重要性逐次递减: 
       LOG_EMERG : 系统无法使用 
       LOG_ALERT : 必须要立即采取反应行动 
       LOG_CRIT : 重要状况发生 
       LOG_ERR : 错误状况发生 
       LOG_WARNING : 警告状况发生 

       LOG_NOTICE : 一般状况,但也是重要状况 
       LOG_INFO : 资讯讯息 
       LOG_DEBUG : 除错讯息

closelog

void closelog( void ) 

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客