Linux系统应用编程(二)进程

Linux系统应用编程(二)进程

一、进程的创建

1.fork( )的理解
  • fork( )函数是Linux/Unix操作系统下的一个系统调用函数,用于创建一个新的进程,该进程是调用fork( )进程的子进程。

  • 特点:子进程拷贝复制父进程的内容,包括代码段、数据段、堆和栈的数据,父子进程在单独的内存空间中运行,虽然子进程复制了父进程的大部分内容,但是由于运行的地址空间是独立的,在执行文件写入、映射等操作时不会互相影响。(man手册所述)

  • 另外,man手册中还介绍了一些父子进程的区别和特点:

    ①子进程拥有自己唯一的进程ID(PID唯一);

    ②进程资源利用率和CPU时间计数器在子进程中会被重置为0;

    ③子进程不会继承父进程的锁和信号量;

    ④子进程不会继承未完成的异步I/O操作;

    ⑤子进程的终止信号始终为SIGCHLD;

    ⑥父子进程共享同一个文件描述符(也就是共享一个文件的I/O属性,包括文件指针偏移量、状态标志等);

    ⑦父子进程共享同一个消息队列。

    (更多详细可自行翻译man手册,这里就记个几点够面试掰扯掰扯就行)

2.fork( )的使用

▲ 返回值:fork( )会返回两次,分别在父进程和子进程中返回。

  • 在父进程中,fork( )返回子进程的pid(正整数,父进程可以通过该子进程pid来操作子进程,如:发送信号kill( )、等待子进程结束wait( )等)

  • 在子进程中,fork( )返回值为0(只作区分父子进程,并不是意味着子进程pid=0)

    返回-1表示创建进程失败

3.vfork( )的理解
  • 特点:在vfork( )函数中,子进程是在父进程的地址空间上运行的,不同于fork( )函数,vfork( )不拷贝复制父进程的内容。因此,vfork( )在运行效率上也比fork( )高效,但在使用上比fork( )函数更复杂,需要注意以下:

    ①vfork( )函数中,父子进程共享地址空间,子进程可修改父进程的变量和函数调用,可能会导致出现问题;

    ②vfork( )函数中,子进程不能使用父进程的栈空间,需要在子进程中重新分配新的栈空间;

    ③vfork( )函数中,子进程先运行,且需要调用exec函数族中的或者exit( )函数结束子进程,父进程才能执行;

    ④vfork( )函数中,子进程不继承父进程的文件描述符,因此如果子进程需要使用同一个文件,需要重新在子进程中打开文件。

二、进程的退出

1.进程退出的方式
  • main函数中return
  • 进程调用标准c库函数exit( )
  • 进程调用系统调用函数 _exit( )或 _Exit( )
  • 进程中最后一个线程return或者调用pthread_exit( )简单说就是进程的最后一个线程结束
  • 异常退出:调用abort( )、收到退出或终止信号等
2.僵尸进程和孤儿进程
  • 僵尸进程:子进程比父进程先结束,且子进程退出状态不被父进程收集,此时子进程将成为一个僵尸进程

  • 孤儿进程:父进程先结束,子进程还在运行,此时子进程将成为一个孤儿进程(孤儿进程将被init进程收养)

3.wait( )、waitpid( )函数

在这里插入图片描述

三、exec族函数

1.作用

​ 在进程中执行另一个可执行程序(二进制文件、shell脚本等),执行后,原进程除了PID外,其他均被可执行程序进程替代。其中,execlp( )会从系统环境变量中寻找可执行程序
(注意:exec函数并不创建新进程,且调用其他程序结束,原程序不再执行)

2.exec族函数原型
#include <unistd.h>
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
3.参数和返回值

在这里插入图片描述

四、system( )函数

在这里插入图片描述

五、popen( )函数

在这里插入图片描述

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

int main(){
    
    
    FILE *file = NULL;
    file = popen("ls -l /","r");
    if(file == NULL){
    
    
        perror("popen");
        exit(-1);
    }
    char *readBuffer = (char *)malloc(128);
    fread(readBuffer,128,1,file);
    printf("read:%s\n",readBuffer);
    pclose(file);

    return 0;
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_54429787/article/details/129927378