linux 进程操作

来源:互联网 发布:评价算法 编辑:程序博客网 时间:2024/05/22 16:02

一.进程创建相关

1. 程序是静态的,没有执行的概念,进程是动态的,是程序的执行过程,包括动态创建,调度和消亡的过程。

       2.   PCB task_struct #include<linux/sched.h>

              PID PPID

              Getpid(), getppid()

              进程包括 代码段 数据段 和堆栈段

       3.  

              Fork返回值如果大于0,是父进程的返回值,0 为子进程的返回值

       子进程从父进程中继承了整个进程的地址空间,包括进程上下文,进程堆栈,内存信息,打开的文件描述符,信号控制设定,进程优先级,进程组号当前工作目录,根目录,资源限制,控制终端等,而子进程所独有的就是它的进程号,资源使用和计数器。

              一般而言现在进程的创建都使用copy-on-write技术

             

              Exec函数族提供了一个进程中启动另一个程序执行的方法。

              一般情况下,都是使用这种方法,是的好像通过应用程序产生了一个新的进程。

              Execl list 表示参数逐个列举的方式

              Execv vertor 表示将所有参数整体构造指针数组传递

              Execle enviroment 可传递新进程环境变量

              Execlp 可执行文件查找方式为文件名    

 

              例如,

(1) execlp(“ps”,”ps”,”-ef”,NULL)

              List + p 以文件名得方式查找,所以第一参数 文件名为 ps”

              List 参数逐个列举的方式 ps” “-ef” NULL

             

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

没有P,表示是按照路径来查找执行文件

 

(3)  char *envp[]={“PATH=/tmp”,”USER=sunq”,NULL};

execle(“/bin/env”,”env”,NULL,envp)

envp就是传递的环境变量

 

(4)   execve

                     Char *arg[]={“evn”,NULL} 命令列表

                     char *envp[]={“PATH=/tmp”,”USER=sunq”,NULL}; 命令参数列表

                     execve(“/bin/env”,arg,envp)

      

              事实上,最终调用的均为execve

4.    exit_exit

exit在退出之前检查文件打开情况,将文件缓存区中的内容写回文件,即清理I/O缓存。而_exit则直接退出

举个例子的话,是printf

PrintfIO缓冲方式的函数,在函数遇到“/n”是自动将数据从缓冲区中读出

例如调用

Printf(“test1/n”;printf(“test2”);

调用exit0)的话 会显示 test1 test2

如果调用_exit(0),则之显示test1

 

5.        waitwaitpid

waitwaitpid的一个特例,

status NULL,表示以任意状态结束的子进程

非空 则表示 指定状态结束的子进程

函数的返回值 0 表示没有子进程退出(只在非阻塞模式下有意义)

正常时,返回子进程的进程号

              wait是阻塞等待子进程的结束,而waitpid也可以设置非阻塞模式等待进程退出

              例如,

                     Pc=fork();

                     If(pc>0) //父进程

                     {     //以任意状态结束的子进程

                            Do

{

Pr=Waitpid(pc,NULL,WNOHANG)//非阻塞,

                                   Printf(“wait …/n”);

                                   Sleep(1);

}while(pr==0)                         

}

       如果使用waitpid(pc,NULL,0)//则为阻塞模式,直到指定的子进程退出为止、

 

二.Linux下守护进程创建(用户空间)

       守护进程,daemon进程,是linux下的后台服务程序,通常独立于控制终端并且周期性的执行某个任务或者等待某个事件的发生。

       一般在控制终端运行的程序都依附于这个终端,当终端关闭,则对应的进程会自动关闭,而守护进程则脱离了这种限制。

       守护进程的编写步骤

       1.    创建子进程 父进程退出

这么操作的原因是因为 守护进程需要脱离控制终端,父进程退出之后,控制终端认为该进程已经结束,从而脱离控制终端。而此时该子进程没有父进程,有init进程作为其父进程。

       2.    在子进程中创建新的对话

              使用setsid()

       该函数用于创建一个新的会话,并且担任该会话组的组长。(否则还受原来的会话组和进程组的控制,因为子进程继承了父进程的会话组,进程组,控制终端

       这样,进程就脱离了原来会话组控制,摆脱原来进程组的控制,摆脱原控制终端的控制。

       具体的会话组 与进程组的关系如下图所示

                         

 

 

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

              由于子进程继承了父进程的当前工作目录,为了保证不会受目录的影响(比如mount出来的目录),将根目录作为守护进程的目录

              Chdir(“/”)

4.        重设文件权限掩码

由于子进程继承了父进程的权限掩码,摆脱该权限掩码,自己设定进程的权限掩码

Umask0

5.        关闭文件描述符

因为守护进程已经脱离了控制终端,所以终端对应的标准输入0,标准输出1,标准出错2的文件描述符没有存在的意义,将这些描述符关闭,释放资源。

#define MAXFILE 65535 //

For(i=0;i<MAXFILE;i++)

       Close(i);

三.守护进程的出错调试

       因为守护进程脱离了控制终端,所以只能通过写文件的方式进行调试

       使用openlog,closelog,syslog

       对应的log文件在/var/log/message

       Openlog(“XXX”,LOG_PID,LOG_DAEMON);

       Syslog(LOG_ERR,”open”);