感谢支持
我们一直在努力

Linux 进程控制入门

本来想现在Linux上熟悉下进程的有关概念然后去写windowsSDK的,没想到今天Windows蓝屏了,新升级的3.2.2内核打开虚拟机的时候还要升级内核。升就升吧,没想到还错误了。没办法,看来只好在Linux上面待着了。


这几天自己只是熟悉了下进程的概念,然后简单的写了一些小程序。自己写点笔记免的忘掉。


进程标识符:Linux环境下进程启动时候,系统分配给一个唯一的数值给每个进程,这个数值就称为进程标识符。(感觉跟windows里面的句柄有点像)


进程表示有进程号 PID 和 父进程号 PPID,都是非0整数


使用函数getpid获得当前进程号,


函数原型Pid_t getpid(void);




使用函数getppid获得当前进程的父进程号


函数原型Pid_t getppid(void);




下面介绍LinuxC下与进程相关的函数


exec函数族  在进程中启动另一个程序执行


这个函数族有6个成员



exec函数族函数原型


#include <unistd.h>


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


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


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


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


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


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

其中只有execve是真正意义上的系统调用,其它都是在此基础上经过包装的库函数。

system          在进程中开始另一个进程


       函数原型


       #i nclude<stdlib.h>
       int system(const char * string);


       函数说明
       system()会调用fork()产生子进程,由子进程来调用/bin/sh-c string来执行参数string字符串所代表的命令,此命>令执行完后随即返回原调用的进程。在调用system()期间     SIGCHLD 信号会被暂时搁置,SIGINT和SIGQUIT 信号则会被忽略。
       返回值
        =-1:出现错误
        =0:调用成功但是没有出现子进程
        >0:成功退出的子进程的id


fork                 从已存在的进程中复制一个新进程(这个进程叫做原来父进程的子进程)


        这是个关键的函数,理解了这个函数也就是进程入门了吧,呵呵


        废话不多说,先来看看函数原型:


          #include<unistd.h>  


                #include<sys/types.h>  


          pid_t fork( void);   (pid_t 是一个宏定义,其实质是int 被定义在#include<sys/types.h>中)


返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1   


函数说明:   一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process)。fork函数被调用一次但返回两次。两次返回的唯一区别是子进程中返回0值而父进程中返回子进程ID。   


子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。注意,子进程持有的是上述存储空间的“副本”,这意味着父子进程间不共享这些存储空间。  


Linux将复制父进程的地址空间内容给子进程,因此,子进程有了独立的地址空间。


我当初一直难以理解的fork函数的返回值。先看下示例代码:


[cpp]


  1. #include <stdio.h>   

  2. #include <stdlib.h>   

  3. #include <unistd.h>   

  4. #include <sys/types.h>   

  5.   

  6. int main()  

  7. {  

  8.     //unsigned int result;     

  9.     pid_t result;  

  10.     result=fork();  

  11.     int newret;  

  12.     if (result==-1)  

  13.     {  

  14.         perror(“创建子进程失败”);  

  15.         exit;  

  16.     }  

  17.     else if (result == 0)  

  18.     {  

  19.         printf(“返回值是:%d,说明这是子进程!\n 此进程的进程号(PID)是:%d\n此进程的父进程号(PPID)是:%d\n”,result,getpid(),getppid());  

  20.         newret = system(“ls -l”);  

  21.     }  

  22.     else  

  23.     {  

  24.         sleep(10);  

  25.         printf(“返回值是:%d,说明这是父进程!\n 此进程的进程号(PID)是:%d\n此进程的父进程号(PPID)是:%d\n”,result,getpid(),getppid());  

  26.         newret = system(“ping www.baidu.com”);  

  27.     }  

  28.     return 0;  

  29. }     
这个例子根据返回值判断当前进程是父进程还是子进程。再回头看看概念解释,应该能明白了吧,呵呵。


sleep             让进程暂停执行一段时间


                      函数原型:


                      #include <unistd.h>


                      unsigned int sleep (unsigned int seconds);


比如,可以使用 sleep(10);    让当前进程睡上10秒钟


 


exit                  终止进程


_exit               终止进程


                     函数原型:


                     #include <stdlib.h>


                     void exit(int status);


                     void _exit(int status);


这里必须说明的是:_exit()直接使进程停止运行,清除其使用的内存空间,清除内核中的数据结构。


                                      exit()则在执行退出前加了若干道工序,把文件缓冲区的内容写到文件,最后调用_exit(),所以我们一般都使用exit()




wait                暂停父进程,等待子进程运行完成


waitpid          暂停父进程,等待子进程运行完成


了解这两个函数的作用,首先要了解僵尸进程的概念:


僵尸进程是值已经终止运行,但尚未被清除的进程。它的本质是一种数据结构。


当使用fork函数创建子进程时,子进程比父进程晚终止,父进程已经结束了,子进程还没终止,子进程就是僵尸进程了。所以我们才要用上面两个函数来避免僵尸进程的产生


                    下面列出函数原型:


                  #include<sys/types.h> 


                  #include<sys/wait.h> 


                     pid_t wait(int *status);


                  pid_t waitpid(pid_t pid,int * status,int options);


因为wait只是waitpid的一种特殊状态,所以这里只说下waitpid


waitpid函数返回值是子进程的PID,这里的第三个参数可以是0,也可以是WNOHANG   WUNTRACED


使用WNOHANG可以使进程不阻塞而直接执行后面的代码。

赞(0) 打赏
转载请注明出处:服务器评测 » Linux 进程控制入门
分享到: 更多 (0)

听说打赏我的人,都进福布斯排行榜啦!

支付宝扫一扫打赏

微信扫一扫打赏