进程处理操作

一、使用system函数调用进程

cpp 复制代码
#include<stdio.h>
#include<stdlib.h>

int main(int argc, char const *argv[])
{
    //使用标准函数创建自进程
    /*
    const char *__command 使用linux命令直接创建一个子进程
    return:成功返回0 失败返回失败编号
    int system (const char *__command)
    */
    int sysR=system("ping -c 10 www.lxl.com");
    if (sysR != 0 )
    {
        perror("system");
        exit(EXIT_FAILURE);
    }
    
    return 0;
}

makefile

cpp 复制代码
CC:=gcc
system_test:system_test.c
	-$(CC) -o $@ $^
	-./$@
	-rm ./$@

二、进程处理相关系统调用

1、main函数说明

2、fork创建子进程

cpp 复制代码
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>

int main(int argc, char const *argv[])
{
    //调用fork之前 代码都在父进程中运行
    printf("海哥教老学员%d春暖花开\n",getpid());
    
    //使用fork创建子进程
    /*
    不需要传参
    return int 进程号
    【1】:-1出错
    【2】:父进程中表示子进程的PID
    【3】:子进程中显示为0
    __pid_t fork (void)
    */
    pid_t pid = fork();
    //从fork之后 所有的代码都是在父进程中各自执行一次的
    //printf("%d\n",pid);

    if (pid < 0)
    {
        printf("新学员加入失败\n");
        return 1;
    }
    else if (pid == 0)
    {
        //执行单独子进程代码
        printf("新学员%d加入成功,他是老学员%d推荐的\n",getpid(),getpid());
    }
    else
    {
        //执行单独父进程代码
        printf("老学员%d继续深造,他推荐了%d\n",getpid(),pid);
    }

    return 0;
}

makefile

cpp 复制代码
fork_test:fork_test.c
	-$(CC) -o $@ $^
	-./$@
	-rm ./$@

3、使用fork复制文件描述符

cpp 复制代码
#include<sys/stat.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>

int main(int argc, char const *argv[])
{
    //fork之前 父进程单独进

    int fd = open("io.txt",O_CREAT | O_WRONLY |O_APPEND,0644);

    if (fd == -1)
    {
        perror("open");
        exit(EXIT_FAILURE);
    }
    char buffer[1024];//缓冲区存放写出的数据

    pid_t pid = fork();
    
    if (pid < 0)
    {
        perror("fork");
        exit(EXIT_FAILURE);
    }
    else if (pid == 0)
    {
        //子进程代码
        strcpy(buffer,"这是子进程写入的数据!\n");
    }
    else
    {
        //父进程代码
        sleep(1);
        strcpy(buffer,"这是父进程写入的数据!\n");
    }
    
    //父子进程都要执行的代码
    ssize_t bytes_write = write(fd,buffer,strlen(buffer));
    if (bytes_write == -1)
    {
        perror("write");
        close(fd);
        exit(EXIT_FAILURE);
    }
    printf("写入数据成功\n");

    //使用完毕之后关闭
    close(fd);

    if (pid == 0)
    {
        printf("子进程写入完毕,并释放文件描述符\n");
    }
    else
    {
        printf("父进程写入完毕,并释放文件描述符\n");
    }
    

    return 0;
}

makefile

cpp 复制代码
fork_fd_test:fork_fd_test.c
	-$(CC) -o $@ $^
	-./$@
	-rm ./$@

4、execve

exec系列函数可以在同一进程中跳转执行另外一个程序

(1)execve单独使用

cpp 复制代码
//erlou.cpp内容
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

int main(int argc, char const *argv[])
{
    if (argc < 2)
    {
        printf("参数不够,不能上二楼");
        return 1;
    }
    printf("我是%s 编号%d 父进程编号%d,我跟海哥上二楼了\n",argv[1],getpid(),getpid());
    
    return 0;
}

makefile

cpp 复制代码
erlou:erlou.c
	-$(CC) -o $@ $^
	
cpp 复制代码
//execve_test.cpp内容
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

int main(int argc, char const *argv[])
{
    //跳转之前
    char *name="banzhang";
    printf("我是%s 编号%d 父进程编号%d,我现在还在一楼\n",name,getpid(),getpid());
    /*
    const char *__path 执行程序的路径
    char *const __argv[] 传入的参数与main函数中argv是对应的
        【1】第一个参数固定是程序的名称
        【2】执行程序需要传入的参数
        【3】最后一个参数一定是NULL
    char *const __envp[] 传递的环境变量
        【1】环境变量参数:key=value
        【2】最后一个参数一定是NULL
    return 成功根本没办法返回 下面的代码没有意义,失败返回 -1
    跳转前后只有进程号保留下来,别的变量都删除了
    int execve(const char *__path, char *const __argv[], char *const __envp[])
    */
    //执行跳转 
    char *args[]={"/home/lxl/process_test/erlou",name,NULL};
    char *envs[]={NULL};
    int re= execve(args[0],args,envs);
    if (re == -1)
    {
        printf("你没有机会上二楼");
        return 1;
    }
    
    //此处的代码没有意义,因为程序跳转了,不会再往下执行了

    return 0;
}
cpp 复制代码
execve_test:execve_test.c
	-$(CC) -o $@ $^
	-./$@
	-rm ./$@

(2)execve+fork

可以fork和exec共同使用,实现场景老学员推荐新学员在二楼学习,自己保持不变。

cpp 复制代码
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

int main(int argc, char const *argv[])
{
    //跳转之前
    char *name="banzhang";
    printf("我是%s 编号%d 父进程编号%d,我现在还在一楼\n",name,getpid(),getppid());
    /*
    const char *__path 执行程序的路径
    char *const __argv[] 传入的参数与main函数中argv是对应的
        【1】第一个参数固定是程序的名称
        【2】执行程序需要传入的参数
        【3】最后一个参数一定是NULL
    char *const __envp[] 传递的环境变量
        【1】环境变量参数:key=value
        【2】最后一个参数一定是NULL
    return 成功根本没办法返回 下面的代码没有意义,失败返回 -1
    跳转前后只有进程号保留下来,别的变量都删除了
    int execve(const char *__path, char *const __argv[], char *const __envp[])
    */
    //执行跳转 
    char *args[]={"/home/lxl/process_test/erlou",name,NULL};
    char *envs[]={NULL};
    int re= execve(args[0],args,envs);
    if (re == -1)
    {
        printf("你没有机会上二楼");
        return 1;
    }
    
    //此处的代码没有意义,因为程序跳转了,不会再往下执行了

    return 0;
}

makefile

cpp 复制代码
fork_execve_test:fork_execve_test.c
	-$(CC) -o $@ $^
	-./$@
	-rm ./$@

5、waitpid

cpp 复制代码
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>

int main(int argc, char const *argv[])
{
    //fork之前
    int subprocess_status;
    printf("老学员%d在校区\n",getpid());
    pid_t pid = fork();
    if (pid < 0)
    {
        perror("fork");
        return 1;
    }
    else if (pid == 0)
    {
        char* args[]={"/usr/bin/ping","-c","10","www.lxl.com",NULL};
        char*envs[]={NULL};
        printf("新学员%d联系老学员%d 10次\n",getpid(),getppid());
        int exeR = execve(args[0],args,envs);
        if (exeR < 0)
        {
           perror("execve");
           return 1;
        }
    }
    else
    {
        printf("老学员%d等待新学员%d联系\n",getpid(),pid);
        waitpid(pid,&subprocess_status,0);
    }
    printf("老学员等待新学员联系完成\n");
    return 0;
}

makefile

cpp 复制代码
waitpid_test:waitpid_test.c
	-$(CC) -o $@ $^
	-./$@
	-rm ./$@
相关推荐
随意起个昵称13 分钟前
线性dp-综合刷题1(Not Alone)
算法·动态规划
asdfg125896320 分钟前
C 语言中产生伪随机数的标准做法
c语言·开发语言
玖玥拾24 分钟前
C/C++ 基础笔记(十一)类的进阶
c语言·c++·设计模式·
KobeSacre32 分钟前
JUC 概述
java·开发语言
-森屿安年-35 分钟前
1137. 第 N 个泰波那契数
c++·动态规划
Jun6261 小时前
QT(2)-通过管道关联CMD
开发语言·qt·命令模式
如何原谅奋力过但无声1 小时前
【灵神高频面试题合集09-13】二叉树、二叉搜索树
数据结构·算法·leetcode
程序员老舅1 小时前
从内核视角,看Linux文件读写过程
linux·服务器·c++·内核·linux内核·vfs·linux内存
皆圥忈1 小时前
磁盘物理结构与文件系统基础讲解
linux·算法
数据仓库搬砖人1 小时前
用 LangGraph 从零搭一个客服 Agent:多轮对话 + 工具调用全流程
算法