Linux系统编程1、fork函数 getpid函数 父子进程共享 不共享2、execl换壳 -后台进程打印到文件 3、孤儿进程 僵尸进程 4、wait和waitpid回收子进程

1、fork函数

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


int main(int argc, char * argv[])
{
    printf("before fork1\n");
    printf("before fork2\n");
    printf("before fork3\n");
    printf("before fork4\n");
    printf("before fork5\n");
    printf("before fork6\n");
    pid_t pid1;
    pid1 = fork();
    if (pid1 == -1)
    {
        perror("fork error");
        exit(1);
    }
    else if (pid1 == 0) // 子进程
    {
        printf("---child is created---\n");
    }
    else if (pid1 > 0)
    {
        printf("---parent process--- : my child is %d\n", pid1);
    }

    printf("============end of file\n");

    return 0;
}

1、fork函数循环创建n个子进程 

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


int main(int argc, char *argv[])
{
    printf("before fork1\n");
    printf("before fork2\n");
    printf("before fork3\n");
    printf("before fork4\n");
    printf("before fork5\n");
    printf("before fork6\n");
    int i;
    pid_t pid1;
    for (i = 0; i < 5; ++i)
    {
        pid1 = fork();
        if (pid1 == -1)
        {
            perror("fork error");
            exit(1);
        }
        else if (pid1 > 0)
        {
            if (i == 0)
                printf("parent process: %d\n", getpid());
            usleep(1);
        }
        else
        {
            printf("I'm %d child procee: %d myparentpid %d\n", i + 1, getpid(), getppid());
            break;
        }
    }
    
    printf("====end of file====\n");

    return 0;
}

1、getpid函数

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


int main(int argc, char * argv[])
{
    printf("before fork1\n");
    printf("before fork2\n");
    printf("before fork3\n");
    printf("before fork4\n");
    printf("before fork5\n");
    printf("before fork6\n");
    pid_t pid1;
    pid1 = fork();
    if (pid1 == -1)
    {
        perror("fork error");
        exit(1);
    }
    else if (pid1 == 0) // 子进程
    {
        printf("---child is created---\n");
        printf("my pid: %d, my parent pid: %d\n", getpid(), getppid());
    }
    else if (pid1 > 0)
    {
        printf("---parent process--- : my child is %d\n", pid1);
        printf("my pid: %d, my parent pid: %d\n", getpid(), getppid());
    }

    printf("============end of file\n");

    return 0;
}

1、父子进程共享 不共享

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
// 定义1个全局变量
int var = 100; // 测试父子进程是否共享全局变量
// 不共享, 读时共享, 写时复制

int main(int argc, char *argv[])
{
    pid_t pid;
    pid = fork();

    if (pid == -1)
    {
        perror("fork error");
        exit(1);
    }
    else if (pid > 0)
    {
        // 父进程
        var = 288;
        printf("parent, var = %d\n", var);
        printf("I'm parent pid = %d, getppid = %d\n", getpid(), getppid());
    }
    else if (pid == 0)
    {
        // 子进程
        // var = 200;
        printf("I'm child pid = %d, ppid = %d\n", getpid(), getppid());
        printf("child, var = %d\n", var);
    }


    return 0;
}

2、execl换壳函数 -后台进程打印到文件

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

int main(int argc, char *argv[])
{
    // 重定向输出--某文件
    int fd1 = open(argv[1], O_RDWR | O_CREAT, 0644);
    if (fd1 == -1)
    {
        perror("open error");
        exit(1);
    }
    int fd2 = dup2(fd1, STDOUT_FILENO);
    if (fd2 == -1)
    {
        perror("dup2 error");
        exit(1);
    }
    // 执行ps aux
    int ret = execlp("ps", "ps", "-a", "-u", "-x", NULL);
    if (ret == -1)
    {
        perror("execlp error");
        exit(1);
    }


    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

int main(int argc, char *argv[])
{
    printf("----before fork1----\n");
    printf("----before fork2----\n");
    printf("----before fork3----\n");
    printf("----before fork4----\n");
    printf("----before fork5----\n");
    pid_t pid;
    int ret;
    pid = fork();
    if (pid == -1)
    {
        perror("fork error\n");
        exit(1);
    }
    else if (pid > 0)
    {
        sleep(1);
        printf("Father process: %d, child process: %d\n", getpid(), pid);
    }
    else
    {
        printf("child process: %d, myfather process: %d\n", getpid(), getppid());
        // ret = execl("./test", "./test", NULL);
        // ret = execl("./", "test", NULL);
        ret = execl("/bin/ls", "/bin/ls", NULL);
        if (ret == -1)
        {
            perror("execlp error");
            exit(1);
        }
    }
    printf("====end of file====\n");

    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

int main(int argc, char *argv[])
{
    printf("----before fork1----\n");
    printf("----before fork2----\n");
    printf("----before fork3----\n");
    printf("----before fork4----\n");
    printf("----before fork5----\n");
    pid_t pid;
    int ret;
    pid = fork();
    if (pid == -1)
    {
        perror("fork error\n");
        exit(1);
    }
    else if (pid > 0)
    {
        sleep(1);
        printf("Father process: %d, child process: %d\n", getpid(), pid);
    }
    else
    {
        printf("child process: %d, myfather process: %d\n", getpid(), getppid());
        // ret = execlp("ls", "ls", "-l", "-h", NULL); // NULL代表参数结束(手动加)
        ret = execlp("date", "date", NULL);
        if (ret == -1)
        {
            perror("execlp error");
            exit(1);
        }
    }
    printf("====end of file====\n");

    return 0;
}

3、 孤儿进程

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

int main(void)
{
    pid_t pid;
    pid = fork();
    if (pid == -1)
    {
        perror("fork error");
        exit(1);
    }
    else if (pid > 0)
    {
        printf("I'm parent, my pid is = %d\n", getpid());
        sleep(9);
        printf("----parent going to die----\n");
    }
    else
    {
        while(1)
        {
            printf("I'm child, my parent pid = %d\n", getppid());
            sleep(1);
        }
    }

    return 0;
}

3、僵尸进程

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

int main(void)
{
    pid_t pid;
    pid = fork();
    if (pid == -1)
    {
        perror("fork error");
        exit(1);
    }
    else if (pid > 0)
    {
        while(1)
        {
            printf("I'm parent, pid = %d, my son pid = %d\n", getpid(), pid);
            sleep(1);
        }
    }
    else
    {
        
        printf("child, my parent = %d, going to sleep 10s\n", getppid());
        sleep(10);
        printf("----child die----\n");
    }

    return 0;
}

4、wait回收子进程 查看死因

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

int main(int argc, char *argv[])
{
    pid_t pid, wpid;
    pid = fork();

    int status; // 记录子进程死亡原因

    if (pid == -1)
    {
        perror("fork error");
        exit(1);
    }
    else if (pid > 0)
    {
        wpid = wait(&status);
        if (wpid == -1)
        {
            perror("wait error");
            exit(1);
        }
        printf("----parent wait(%d) finished\n", wpid); // 阻塞等待回收子进程(子不死, 父不回收)
        // 查看子进程死亡原因
        if (WIFEXITED(status)) // 子进程正常死亡的
            printf("子进程return值: %d\n", WEXITSTATUS(status));
        else if (WIFSIGNALED(status)) // 子进程被信号杀死的(非正常死亡)
            printf("子进程被%d号信号杀死\n", WTERMSIG(status));
        
    }
    else
    {
        printf("---child, myid = %d, my parent = %d, going to sleep 10s\n", getpid(), getppid());
        sleep(10);
        printf("-----------------child die------------------\n");

        return 73;
    }


    return 0;
}

4、waitpid指定回收子进程 

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

int main(int argc, char *argv[])
{
    // 循环创建多个子进程
    pid_t pid, wpid;
    int i;
    // int status; // 查看子进程死亡原因
    for (i = 0; i < 5; ++i)
    {
        pid = fork();
        if (pid == -1)
        {
            perror("fork error");
            exit(1);
        }
        else if (pid > 0)
        {
            if (i == 0)
                printf("I'm parent %d\n", getpid());
            // 父进程 // 指定回收第3个子进程
            if (i == 2)
            {
                sleep(5);
                wpid = waitpid(pid, NULL, WNOHANG); // 非阻塞式回收
                if (wpid == -1)
                {
                    perror("waitpid error");
                    exit(1);
                }
                printf("I'm parent, wait a child finish : %d\n", wpid); // 子进程没死
            }
        }
        else
        {
            // 子进程
            sleep(i);
            printf("I'm %dth child mypid = %d\n", i + 1, getpid());
            break;
        }
    }

    return 0;
}

4、waitpid无差别回收子进程 

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


int main(int argc, char *argv[])
{
    // 循环创建多个子进程
    pid_t pid, wpid;
    int i;
    // int status; // 查看子进程死亡原因
    for (i = 0; i < 5; ++i)
    {
        pid = fork();
        if (pid == -1)
        {
            perror("fork error");
            exit(1);
        }
        else if (pid > 0)
        {
            // 父进程
            wpid = waitpid(-1, NULL, WNOHANG); // 非阻塞式回收
            if (wpid == -1)
            {
                perror("waitpid error");
                exit(1);
            }
            printf("I'm parent, wait a child finish : %d\n", wpid); // 子进程没死
        }
        else
        {
            // 子进程
            sleep(i);
            printf("I'm %dth child\n", i + 1);
            break;
        }
    }

    return 0;
}

5、waitpid阻塞回收多个子进程

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

int main(int argc, char *argv[])
{
    // 循环创建多个子进程
    pid_t pid, wpid;
    int i;
    // int status; // 查看子进程死亡原因
    for (i = 0; i < 5; ++i)
    {
        pid = fork();
        if (pid == -1)
        {
            perror("fork error");
            exit(1);
        }
        else if (pid > 0)
        {
            if (i == 0)
                printf("I'm parent %d\n", getpid());
        }
        else
        {
            // 子进程
            sleep(i);
            printf("I'm %dth child mypid = %d\n", i + 1, getpid());
            break;
        }
    }
    if (i == 5) // 只有父进程才会1步1步++到5退出循环, 子进程直接break的
    {
        // 1次wait/waitpid只能回收1个子进程 形参>0指定回收某个 -1回收任意一个子进程
        while ((wpid = waitpid(-1, NULL, 0)) > 0) // 阻塞回收
        {
            if (wpid == -1)
            {
                perror("waitpid error");
                exit(1);
            }
            printf("waitpid(%d)\n", wpid);
        }
    }

    return 0;
}

5、waitpid非阻塞回收多个子进程 

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

int main(int argc, char *argv[])
{
    // 循环创建多个子进程
    pid_t pid, wpid;
    int i;
    // int status; // 查看子进程死亡原因
    for (i = 0; i < 5; ++i)
    {
        pid = fork();
        if (pid == -1)
        {
            perror("fork error");
            exit(1);
        }
        else if (pid > 0)
        {
            if (i == 0)
                printf("I'm parent %d\n", getpid());
        }
        else
        {
            // 子进程
            sleep(i);
            printf("I'm %dth child mypid = %d\n", i + 1, getpid());
            break;
        }
    }
    if (i == 5) // 只有父进程才会1步1步++到5退出循环, 子进程直接break的
    {
        // 1次wait/waitpid只能回收1个子进程 形参>0指定回收某个 -1回收任意一个子进程
        while ((wpid = waitpid(-1, NULL, WNOHANG)) >= 0) // 非阻塞回收
        {
            sleep(1);
            if (wpid == -1)
            {
                perror("waitpid error");
                exit(1);
            }
            printf("waitpid(%d)\n", wpid);
        }
    }

    return 0;
}

阶段练习(fork创建3子进程, execl分别执行, 父进程回收) 

 

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

int main(int argc, char *argv[])
{
    pid_t pid, wpid;
    int i, ret1, ret2, ret3;
    for (i = 0; i < 3; ++i)
    {
        pid = fork();
        if (pid == -1)
        {
            perror("fork error");
            exit(1);
        }
        else if (pid > 0)
        {
            if (i == 0)
                printf("Parent = %d\n", getpid());
        }
        else
        {
            printf("I'm %dth child = %d, myparent = %d\n", i + 1, getpid(), getppid());
            sleep(i);
            if (i == 0)
            {
                ret1 = execlp("ps", "ps", NULL);
                if (ret1 == -1)
                {
                    perror("execl error");
                    exit(1);
                }
            }
            else if (i == 1)
            {
                ret2 = execl("./a.out", "./a.out", NULL);
                if (ret2 == -1)
                {
                    perror("execl error");
                    exit(1);
                }
            }
            else
            {
                ret3 = execl("./b.out", "./b.out", NULL);
                if (ret3 == -1)
                {
                    perror("execl error");
                    exit(1);
                }
            }
            // break;
        }
    }
    if (i == 3) // 父进程回收3个子进程
    {
        while ((wpid = waitpid(-1, NULL, WNOHANG)) >= 0) // 非阻塞回收
        {
            printf("I'm parent waitpid %d\n", wpid);
            sleep(1);
        }
    }

    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汪呈祥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值