Linux中的进程

本文深入讲解Linux中的进程管理,包括fork(), vfork(), getpid(), getppid(), wait()等关键函数的使用,以及进程状态和结构。通过示例代码演示如何创建子进程,解释进程间的关系和等待机制。

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

linux中进程的相关函数:fork(),vfork(),getpid(),getppid(),wait(). 

1.常用的函数:

这些函数是进程中用到的最基本的函数一定要好好掌握。

fork()函数,开辟内存,拷贝父进程的资源(数据段,代码段),新建一个子进程。

vfork()函数,保证了子进程先运行,在exec 和 exit 执行之前与父进程共享数据段,如果在子进程调用这两个函数之前,依赖于父进程的进一步动作,将会造成死锁。

getpid()函数,获取当前进程的pid号。

getppid()函数,获取当前进程父进程的pid号。

wait()函数,用在父进程中,用于等待自己的直系子进程的结束。(必须是等待由自己创建的直系子进程)。

2.进程运行的状态:

进程是程序的执行过程,根据它的生命周期可以划分成3种状态:执行态、就绪态、等待态。它们之间的转换关系图如下图所示:

 3.Linux下的进程结构

Linux系统是一个多进程的系统,它的进程之间具有并行性、互不干扰等特点。也就是说进程之间是分离的任务,拥有各自的权利和义务。每一个进程都运行在各自独立的虚拟地址空间,因此,即使一个进程发生异常,它也不会影响到系统中的其他进程。Linux中的进程包含3个段,分别为"数据段"、“代码段”和“堆栈段”。

  • 数据段存放的是全局变量、常数以及动态数据分配的数据空间(如malloc函数取得的空间)等
  • 代码段存放的是程序代码的数据。
  • 堆栈段存放的是子程序的返回地址、子程序的参数以及程序的局部变量。
#include<stdio.h>
#include<unistd.h>
int main()
{
    pid_t pid = fork();
    if(pid == 0)
    {
        printf("this is child.\n");
    }
    else if(pid > 0)
    {
        printf("this is parent.\n");
    }
    else
    {
        perror("fork.");
    }
    return 0;
}
运行结果

这是Linux的C编程中,用fork()函数创建子进程的一个过程。从执行的结果来看,仿佛是先执行父进程再执行子进程,父进程的优先级能比子进程稍微高一些。fork()函数是一次调用,多次返回。如果创建失败将-1返回给父进程;成功的话将子进程的pid返回给父进程;将0返回给子进程(可以这样理解子进程并没有自己的“儿子”,所以收到的返回值是0)。

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{   int count = 0;
    pid_t pid = vfork();
    if(pid == 0)
    {
        printf("this is child.pid = %d\n",getpid());
        ++count;
        printf("count = %d\n",count);
        _exit(0);
    }
    else if(pid > 0)
    {
        printf("this is parent.pid = %d\n",getpid());
        ++count;
        printf("count = %d\n",count);
    }
    else
    {
        perror("fork.");
    }
    return 0;
}
运行结果

这是vfork()函数,从运行结果分析:vfork()函数保证子进程先执行,在执行exec和exit这两个函数之前,与父进程共享数据段,通过++count,将共享的count变为1,在执行完_exit之后,再执行父进程,父进程通过++count将count变量变为2。

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

int main()
{
    pid_t pid = fork();
    if(pid == 0)
    {
        pid_t pid1;
        pid1 = fork();
        if(pid1 == 0)//父进程的孙子进程
        {
            printf("pid1 = %d\n",getpid());
            sleep(10);
            printf("pid1 end.\n");
        }

        else if(pid1 > 0)//父进程创建的第一个子进程
        {
            printf("pid0 = %d\n",getpid());
            sleep(3);
            printf("pid0 end.\n");
        }
    }
    else if(pid > 0)
    {
        pid_t pid2;
        pid2 = fork();
        if(pid2 == 0)//父进程创建的第二个子进程
        {
            printf("pid2 = %d\n",getpid());
            sleep(2);
            printf("pid2 end.\n");
        }
        else if(pid2 > 0)//父进程
        {
            int status;
            printf("Parent process wait......\n");
            pid_t pid_ret = wait(&status);//wait()函数可以返回等到的子进程的pid号
            printf("pid_ret = %d\n",pid_ret);
        }
    }
    else
    {
        perror("fork.");
    }
    return 0;
}

上面的程序是为了验证父进程中的wait()函数究竟在等待什么?由上面的注释我们可以很清晰的明白创建的进程的结构。通过调整子进程睡眠的时间,我们可以构造各种子进程结束的情况。由此得到wait()函数等的只能是直系子进程。验证结果较为繁琐,就不贴图了。这充分说明“谁的爱人,谁来等!”PS: 父进程等的是pid2。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值