美文网首页
Linux-C-Day3-进程

Linux-C-Day3-进程

作者: 国服最坑开发 | 来源:发表于2023-02-22 18:43 被阅读0次

进程

  • fork

进程复制,子进程依赖父进程执行时长

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

int main(void) {
    pid_t pid;
    char *message;

    pid = fork();
    if (pid < 0) {
        perror("fork failed");
        exit(1);
    }
    // pid = 0; 子线程
    if (pid == 0) {
        // 如果主进程先执行完毕,子进程会提前退出
        message = "This is child process \n";
        sleep(1);
    } else {
        message = "This is the parent \n ";
        sleep(3);
    }

    printf("%s\n", message);
    return 0;
}

执行应用命令

  • execlp
  • execvp
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

/**
 * execlp(), execvp() 会替代当前进程代码,执行后直接结束
 * p: path
 * 第一个参数: 执行文件path
 * 第二个参数(s): 代表 argv[0], argv[1]... , 所以第一个argv, 是要和执行文件同名
 * 最后一个参数以 NULL 结束
 *
 */
int main(void) {

    // 知道全部参数的场景下
    execlp("/usr/local/bin/oss", "oss", "ls", NULL);

    // 以参数数组的形式传进来
    char *cmd = "/usr/local/bin/oss";
    char *args[] = {"oss", "ls", NULL};
    execvp(cmd, args);

    // 正常情况下,不会执行到这里, 除非上面出错。
    perror("exec error");
    exit(1);
}

管道支持

  • getchar
  • putchar
  • toupper
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>

/**
 * 利用特性:exec结束后,原来的文件fd保持打开状态
 * 利用这个机制,可以编写管道程序
 */
int main(void) {
    int ch;
    // EOF : Ctrl-D 退出
    while((ch = getchar()) != EOF) {
        putchar(toupper(ch));
    }
    return 0;
}

应用内执行外部文件

  • fputs
  • dup2
  • execl
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>

/**
 * 把参数文件在程序内部调用 upper 方法
 */
int main(int argc, char *argv[]) {
    int fd;
    if (argc != 2) {
        fputs("usage: wrapper file\n", stderr);
        exit(1);
    }
    // 只读打开文件
    fd = open(argv[1], O_RDONLY);
    if (fd < 0) {
        perror("open");
        exit(1);
    }

    // 把外部文件fd, 复制给 标准输入fd
    dup2(fd, STDIN_FILENO);
    // 关闭原来的文件fd
    close(fd);

    // 执行外部应用,它会从标准输入读取信息
    execl("./upper", "upper", NULL);
    perror("exec ./upper");
    exit(1);
}

僵尸进程

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>


/**
 * 错误示例:主进程不结束,生成僵尸进程。
 * 主进程状态: ps u 的状态为 Z.
 * 此时是无法kill -9 的方法杀掉。
 */
int main(void) {
    pid_t pid = fork();
    if (pid < 0) {
        perror("fork");
        exit(1);
    }

    if (pid > 0) {
        while (1);
    }

    return 0;
}

进程同步

  • waitpid
  • getpid
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>

int main(void) {
    pid_t pid;
    pid = fork();
    if (pid < 0) {
        perror("fork failed:");
        exit(1);
    }
    if (pid == 0) {
        int i;
        for (i = 3; i > 0; i--) {
            printf("This is the child\n");
            sleep(1);
        }
        exit(3);
    } else {
        int stat_val;
        // getpid(): 当前进程id
        // pid : 子线程id
        printf("current pid : %d,  child pid : %d\n", getpid(), pid);

        // 等待子进程结束
        waitpid(pid, &stat_val, 0);

        // 如果子进程以 exit()方式结束,获取其值。
        if (WIFEXITED(stat_val))
            printf("Child exited with code %d\n", WEXITSTATUS(stat_val));
        else if (WIFSIGNALED(stat_val)) // 以中断等方式退出的,走进这里
            printf("Child terminated abnormally, signal %d\n", WTERMSIG(stat_val));
    }
    return 0;
}

进程同信-IPC

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>


#define MAXLINE 80

/**
 * 进程间通信: IPC (InterProcess Communication)
 * pipe(fd[2]) 创建一个管道, fd[0]: 读端,  fd[1]: 写端
 */
int main(void) {
    ssize_t n;
    int fd[2];
    pid_t pid;
    char line[MAXLINE];

    if (pipe(fd) < 0) {
        perror("pipe");
        exit(1);
    }

    if ((pid = fork()) < 0) {
        perror("fork");
        exit(1);
    }

    if (pid > 0) { /* 主进程 */
        /**
         * 主进程只管写,所以先关闭 读端 ?
         */
        close(fd[0]);
        char *msg = "hello world\n";
        write(fd[1], msg, strlen(msg));
        // 写入写端后,等待子进程结束
        wait(NULL);
    } else { /* 子进程 */
        /**
         * 先关闭写端
         */
        close(fd[1]);
        // 从读端读取一行
        n = read(fd[0], line, MAXLINE);
        // 打印到标准输出
        write(STDOUT_FILENO, line, n);
    }

    return 0;
}

相关文章

  • 进程,进程,进程

    1. 进程是具有独立功能的程序关于某个数据集合的一次运行过程。(1)程序本身是静态的,是没有生命周期的,只有运行起...

  • Linux回收子进程

    孤儿进程 孤儿进程: 父进程先于子进程结束,则子进程成为孤儿进程,子进程的父进程成为init进程,称为init进程...

  • Android 五种进程的管理

    安卓有几种进程? 前台进程 可见进程 服务进程 后台进程 空进程 前台进程 用户当前操作所必需的进程。如果一个进程...

  • 孤儿进程、僵尸进程与进程回收

    孤儿进程与僵尸进程 孤儿进程:父亲死了,子进程被init进程领养僵尸进程:子进程死了,父进程没有回收子进程的资源(...

  • 第三章 进程管理

    进程基础 进程基本概念 进程组:只包括祖先进程,子孙进程,兄弟进程进程树:所有进程僵尸进程:在父进程中经常会调用w...

  • Chaprter-1 [进程]

    进程模型 进程定义 进程的创建 进程的终止 进程的层次结构 进程的状态 进程的状态图 进程的实现

  • 进程操作

    一、进程创建 进程树 父进程创建若干子进程,子进程再创建其子进程,依次类推,构成进程树。进程的调度,其实就是在进程...

  • 进程管理(一)进程操作

    进程创建 、进程执行映像和加载、进程运行(进程调度)、进程间的互斥与同步、进程间通信、进程终止 1、进程创建 PC...

  • python中的僵尸进程和孤儿进程

    孤儿进程:父进程退出,子进程还在运行的这些子进程都是孤儿进程,孤儿进程将被 init 进程(进程号为 1)所收养,...

  • 容器中的孤儿进程&僵尸进程简介

    背景简介 孤儿进程 父进程先于子进程退出,那么子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)接管,并...

网友评论

      本文标题:Linux-C-Day3-进程

      本文链接:https://www.haomeiwen.com/subject/yswakdtx.html