进程处理操作

一、使用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 ./$@
相关推荐
代码无bug抓狂人1 小时前
用回溯算法解决01背包
数据结构·算法
Shan12051 小时前
二叉树的遍历算法之中序遍历
算法
兩尛1 小时前
C++多线程编程
开发语言·jvm·c++
晨曦中的暮雨1 小时前
动态规划专题Day1——打家劫舍系列
算法·动态规划
khalil10201 小时前
代码随想录算法训练营Day-52 图论03 | 101.孤岛的总面积、102.沉没孤岛、103.水流问题、104.建造最大岛屿
c++·算法·图论
老四啊laosi1 小时前
[滑动窗口] 13. 水果成篮
算法·leetcode·滑动窗口·水果成篮
刀法如飞1 小时前
Palantir技术原理深度分析:Ontology 存储结构与读写方式
人工智能·算法·架构
澈2072 小时前
图论基础:邻接矩阵与邻接表详解
算法·图论·邻接矩阵
weixin_428005302 小时前
C#调用 AI学习从0开始-第1阶段(基础与工具)-第4天CoT思维链学习
开发语言·学习·ai·c#·cot