进程控制相关系统调用

系统调用:进程控制
fork系统调用
函数作用:创建一个子进程

形式:pid_tfork(void);

pid_t vfork(void);

说明:使用vfork创子进程时,不会进程父进程的上下文

返回值:[返回值=-1]子进程创建失败

[返回值=0]子进程创建成功

[返回值>0]对父进程返回子进程PID

#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
int main() {
    pid_t id = fork();
    if (id < 0) {
        perror("子进程创建失败!");
    } else {
        if (id == 0) {
            printf("子进程工作:PID=%d,PPID=%d\n", getpid(), getppid());
        }else
        {
            printf("父进程工作:PID=%d,PPID=%d,子进程PID=%d\n", getpid(), getppid(),id);
            sleep(5)
        }
    }
}
控制台输出

父进程工作:PID=3173,PPID=2432,子进程PID=3176

子进程工作:PID=3176,PPID=3173

exit系统调用
函数作用:终止发出调用的进程

形式:voidexit(int status);

说明

1.      exit返回信息可由wait系统函数获得

2.      如果父进程先退出子进程的关系被转到init进程下

#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
int main() {
    pid_t id = fork();
    if (id < 0) {
        perror("子进程创建失败!");
    } else {
        if (id == 0) {
            printf("子进程工作:PID=%d,PPID=%d\n", getpid(), getppid());
            sleep(20);
            printf("此时子进程:PID=%d,PPID=%d\n", getpid(), getppid());
        }else
        {
            printf("父进程工作:PID=%d,PPID=%d,子进程PID=%d\n", getpid(), getppid(),id);
            sleep(5);
            exit(3);
        }
    }
    return 0;
}
控制台输出

父进程工作:PID=3068,PPID=2432,子进程PID=3071

子进程工作:PID=3071,PPID=3068

此时子进程:PID=3071,PPID=1

wait系统调用
函数作用:父进程与子进程同步,父进程调用后。进入睡眠状态,直到子进程结束或者父进程在被其他进程终止,

形式:pid_twait(int *status)

pid_t waitpid(pid_t pid ,int *status,int option)

参数:statusè exit是设置的代码

pid è进程号

option: WNOHANG|WUNTRACED

WNOHANG:,即使没有子进程退出,它也会立即返回,不会像wait那样永远等下去.
WUNTRACED:子进程进入暂停则马上返回,但结束状态不予以理会.

返回值:如果成功等待子进程结束,则返回子进程PID。后者为-1

用来检查子进程返回状态的宏

WIFEXITED这个宏用来指出子进程是否为正常退出的,如果是,它会返回一个非零值.

WEXITSTATUS当WIFEXITED返回非零值时,我们可以用这个宏来提取子进程的返回值

wait函数使用
#include <sys/types.h>
#include <sys/uio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
    pid_t cid;
    cid = fork();
    if (cid < 0) {
        perror("子进程创建失败!");
    } else {
        if (cid == 0) {
            printf("子进程工作\n");
            printf("子进程PID=%d,PPID=%d\n", getpid(),getppid());
            //sleep(20); //1
        } else {
            //wait(NULL);//2
            //sleep(20);//3
            printf("父进程工作\n");
            printf("父进程PID=%d,PPID=%d\n", getpid(),getppid());
        }
    }
    return 0;
}
针对上述代码作以下分析:

1.      当子进程退出时,如果父进程没有wait进行回收资源,子进程就会一直变为僵尸进程(Z)直到父进程退出

作法:

打开3处注释后执行程序,查看进程状态,如下

[root@localhostDebug]# ps -C Process -o pid,ppid,stat,cmd

PID PPID STAT CMD

12233 11563S  /root/workspace/Process/Debug/Process

12238 12233Z    [Process] <defunct>

=>可以看到子进程此时的状态时Z(僵尸进程)

控制台输出如下

子进程工作

子进程PID=12238,PPID=12233

(20S后…..)

父进程工作

父进程PID=12233,PPID=11563

2.      使用wait进行进程同步,父进程直到子进程退出,wait才会结束等待

作法:

打开1,2处注释后执行程序,查看进程状态,如下

[root@ Debug8$] ps -C Process -o pid,ppid,stat,cmd

PID PPID STAT CMD

3425 2432 S  /root/workspace/Process/Debug/Process

3430 3425 S  /root/workspace/Process/Debug/Process

=>父进程与子进程都处于sleep状态

控制台输出如下

子进程工作

子进程PID=3430,PPID=3425

(20S后…..)

父进程工作

父进程PID=3425,PPID=2432

3. 使用wait进行进程同步,子进程退出后,父进程结束wait等待,同时清空子进程信息,此时子进程不再是僵尸进程

作法:

打开2,3处注释后执行程序,查看进程状态,如下

[root@localhostDebug]# ps -C Process -o pid,ppid,stat,cmd

PID PPID STAT CMD

1250611563 S  /root/workspace/Process/Debug/Process

=>可以看到此时只有父进程信息

控制台输出如下

子进程工作

子进程PID=12511,PPID=12506

(20S后…..)

父进程工作

父进程PID=12506,PPID=11563

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/18649.html