美文网首页
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;
    }
    

    相关文章

      网友评论

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

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