进程相关函数

本文介绍了Linux系统中与进程管理相关的函数,包括fork用于创建子进程,exec函数族用于替换进程,exit和_exit用于进程退出,以及wait和waitpid用于等待子进程并获取其退出状态。详细讲解了各函数的工作原理和注意事项,如孤儿进程与僵尸进程的产生及避免。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

进程相关函数------>fork exec函数族 exit/_exit   wait/waitpid

1.fork

        作用:创建一个子进程

        (创建方式:子进程复制了父进程的所有的内容,他和父进程的进程号不同)

        pid_t  fork(void);

        无入参

        返回值:创建失败 ,-1

                      创建成功 0或pid(0->子进程  子进程的进程号-->父进程)

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>

int main()
{
    pid_t pid=-1;
    printf("hello nihao!!!!!\r\n");
    pid = fork();
    if(-1 == pid)
    {
        return -1;
    }
    if(0 == pid)//child process
    {
        printf("child process,pid=%d,parent pid=%d\r\n",getpid(),getppid());
    }
    else//pid > 0 parent process
    {
        printf("parent process,parent pid=%d,pid=%d\r\n",getpid(),pid);
    }
    printf("hello word!!!!!!!\r\n");
    return 0;
}

        孤儿进程:父进程先于子进程退出,子进程由init进程收养,此时子进程就是孤儿进程,pstree查看。孤儿进程可单独存在,没有危害。

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>

int main()
{
    pid_t pid=-1;
    printf("hello nihao!!!!!\r\n");
    pid = fork();
    if(-1 == pid)
    {
        return -1;
    }
    if(0 == pid)//child process
    {
        sleep(10);
        printf("child process,pid=%d,parent pid=%d\r\n",getpid(),getppid());
    }
    else//pid > 0 parent process
    {
        printf("parent process,parent pid=%d,pid=%d\r\n",getpid(),pid);
    }
    printf("hello word!!!!!!!\r\n");
    return 0;
}

        僵尸进程: 子进程先于父进程退出,父进程未处理子进程的退出状态,导致该子进程成为一个僵尸进程,僵尸进程占用一个task_struct但是没有相应的地址空间,它会统一参与操作系统的调度,会消耗系统资源,对系统有危害,我们应该避免僵尸进程的产生。ps -aux查看

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>

int main()
{
    pid_t pid=-1;
    printf("hello nihao!!!!!\r\n");
    pid = fork();
    if(-1 == pid)
    {
        return -1;
    }
    if(0 == pid)//child process
    {
        printf("child process,pid=%d,parent pid=%d\r\n",getpid(),getppid());
    }
    else//pid > 0 parent process
    {
        sleep(10);
        printf("parent process,parent pid=%d,pid=%d\r\n",getpid(),pid);
    }
    printf("hello word!!!!!!!\r\n");
    return 0;
}

 2.exec函数族--->替换进程(在一个进程中启动另外一个进程,另外这个进程使用这个进程的所有资源)

        有6个函数,作用相同,传参方式不同。传参方式由 l  v  p   e组合而成

        l:lis以列表的方式传参,最后以NULL结束。

        v:vector以数组方式传参,数组的最后一个元素为NULL。

        e:env环境变量,传参方式同数组。

        p:PATH,在PATH所指的路径中去找可执行程序。

#include<stdio.h>


int main()
{
    printf("hello!!!!!!!\r\n");
    if(-1 == execlp("ls","ls","-l",NULL))
    {
        printf("execlp error!!!!!!!\r\n");
        return -1;
    }
    printf("hello world!!!!!!!/r/n");
    return 0;
}

 

#include<stdio.h>
#include<stdlib.h>

int main(int argc,char *argv[],char *env[])
{
    while(argc--)
    {
        printf("%s\r\n",*argv++);
    }
    prrintf("..........................\r\n");
    while(*env)
    {
        printf("%s\r\n",*env++);
    }
    printf("###########################\r\n");
    printf("%s\r\n",getenv("PWD"));
    return 0;
}

 

#include<stdio.h>
#include<unistd.h>

int main()
{
    char *argv[]={"aaa","bbb","ccc",NULL};
    char *env[]={"PWD=23456test","jiayou",NULL};
    if(-1 == execve("test",argv,env))
    {
        printf("execve error!!!!!!!!!!!\r\n");
        return -1;
    }
    return 0;
}

3.exit/_exit 

exit:退出当前进程,并刷新IO缓冲区

                参数1:表示退出状态值。0表示正常退出,其他为异常退出。

_exit:退出当前进程,不会刷新IO缓冲区

#include<stdio.h>
#include<stdlib.h>

int main()
{
    printf("hello test by@23456---");
//  return 0;
    exit(0);
}
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

int main()
{
    printf("hello test by@23456---");
//  return 0;
//  exit(0);
    _exit(0);
}

4.wait/waitpid

wait:等待子进程退出(任意子进程),接收子进程的退出状态值。

pid_t wait(int *status);

       *status:指向等到子进程的退出状态值的指针

返回值: >0 等到的子进程的pid

               -1出错

注意:wait是一个阻塞函数

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>

int main()
{
    pid_t pid = -1;
    pid = fork();
    if(-1 == pid)
    {
        retuen -1;
    }
    if(0 == pid)
    {
        printf("child process pid=%d\r\n",getpid());
        sleep(5);
        exit(3);
    }
    else
    {
        printf("parent process,pid=%d\r\n",getpid());
        int status = -1;
        pid_t pidTmp = wait(&status);
        printf("pidTmp=%d,status=%d\r\n",pidTmp,WEXITSTATUS(status));
        sleep(10);
    }
}

        waitpid:等待指定子进程的退出状态值,接收子进程的退出状态值。

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

                        pid:指定子进程的pid

                        *status:指向等到的子进程的退出状态值的指针

                        options:0将waitpid函数变成了阻塞函数        

                        WNOHANG:将waitpid函数变成了非阻塞函数,若等到结果,返回等到子进程的pid,若未等到结果,返回0.

                返回值:未等到结果,返回0;等到结果,返回等到的指定子进程的pid

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>

int main()
{
    pid_t pid = -1;
    pid = fork();
    if(-1 == pid)
    {
        retuen -1;
    }
    if(0 == pid)
    {
        printf("child process pid=%d\r\n",getpid());
        sleep(5);
        exit(3);
    }
    else
    {
        printf("parent process,pid=%d\r\n",getpid());
        int status = -1;
//      pid_t pidTmp = wait(&status);
        pid_t pidTmp = -1;
        while(0 == (pidTmp = waitpid(pid,&status,WNOHANG)))
        {
            printf("hello test!!!!!!!!!!!!!!!!\r\n");
            sleep(1);
        }
        printf("pidTmp=%d,status=%d\r\n",pidTmp,WEXITSTATUS(status));
        sleep(10);
    }
}

        阻塞函数:未等到结果,不返回,会一直阻塞当前进程,直到等到结果再返回。

        非阻塞函数:未等到结果,也返回,不影响当前进程的执行,通过多次循环调用,非阻塞函数去等结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值