进程处理操作

一、使用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 ./$@
相关推荐
名字还没想好☜19 小时前
Python f-string 进阶:数字格式化、对齐填充、调试 = 号与嵌套表达式
开发语言·数据库·python·字符串格式化·f-string
.道阻且长.19 小时前
2.LeetCode算法习题讲解--双指针--复写零
算法·leetcode·职场和发展
·薯条大王20 小时前
经济实惠玩云服务器|一台云服务器多人共用,子账号配置教程
java·linux·运维·服务器·汇编·c++·python
To_OC21 小时前
LC 438 找到所有字母异位词:暴力超时后,我靠滑动窗口一招搞定
javascript·算法·leetcode
一壶浊酒..1 天前
Scrape Webpack练习
开发语言·javascript·webpack
命运之光1 天前
【C语言完整代码】就诊信息管理系统
java·c语言·开发语言
命运之光1 天前
【C语言完整代码】图书管理系统:图书馆场景下的增删改查实战
c语言·开发语言
猿长大人1 天前
C# | Serilog 新手入门
开发语言·c#·.net·log
Forever Nore1 天前
学完C语言力扣第一题做不来正常吗
数据结构·算法