进程处理

笔记 · 8 天前 · 16 人浏览

  进程处理是操作系统中的一个核心概念,它涉及到进程的创建、调度、执行、通信、终止以及资源管理等多个方面。

一、进程的定义与特性

定义:进程是程序的一次执行过程,是系统进行资源分配和调度的一个独立单元。它是动态范畴的概念,与静态的程序不同。
特性:进程具有独立性、动态性、并发性、异步性、结构特征等。每个进程都有自己独立的内存空间和系统资源。

二、代码示例

常用处理参数说明。使用时,多注意僵尸进程和孤儿进程。手动创建手动回收

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

#define PATH ("/usr/bin/ping")
#define WEBSITE ("www.just1n.cn")

int main(int argc, char **argv)
{
    // 使用标准库函数创建子进程
    /**
     * system (const char *__command)
     * const char * __command:使用Linux命令直接创建
     * return:成功返回0, 失败返回失败编号
     */
    int res_sys = system("ping -c 30 www.baidu.com");
    if(res_sys)
    {
        perror("system");
        exit(EXIT_FAILURE);
    }
    // 调用 fock 之前,代码都在父进程中运行
    // 子进程开始前
    printf("__This is a parent process__\n");

    int subProcess_status;

    // 使用 fock 创建子进程
    /**
     * 不需要传参
     * return: int 进程号
     *          (1):-1 出错
     *          (2): 父进程中表示子进程的PID
     *          (3): 子进程中显示为 0
     */
    pid_t pid = fork();
    // 从fork之后  所有的代码都是在父子进程中各自执行一次的
    if (pid < 0)
    {
        perror("fork error");
        exit(EXIT_FAILURE);
    } else if (pid == 0)
    {
        // 子进程
        char *args[] = {PATH, "-c", "10", WEBSITE, NULL};
        char *envs[] = {NULL};
        printf("__Accessing the website__PID_%d_\n", getpid());
        // 执行跳转 : 跳转前后只有进程号保留了下来,别的变量都删除了
        /**
         * int execve (const char *__path, char *const __argv[], char *const __envp[])
         * const char *__path:执行程序的路径
         * char *const __argv[]:传入的参数  -->  对应执行程序main方法的第二个参数
         *          (1).第一个参数固定是程序的名称  -->   执行程序的路径
         *          (2).执行程序需要传入的参数
         *          (3).最后一个参数一定是NULL
         * char *const __envp[]:传递的环境变量:
         *          (1).环境变量参数  =>   key=value
         *          (2).最后一个参数一定是NULL
         * return:成功根本没办法返回,下面的代码也没有意义。失败返回 -1
         */
         int res_exe = execve(args[0], args, envs);
         if(res_exe < 0)
         {
             perror("execve");
             exit(EXIT_FAILURE);
         }
         } else
         {
            // 父进程
            printf("__parent process: %d__ waiting __child process: %d__\n", getpid(), pid);
            waitpid(pid, &subProcess_status, 0);
         }

    printf("waiting is ok!\n");
}

Makefile

CC := gcc
processes : processes.c
    - $(CC) -o $@ $^  # 编译
    -./$@             # 运行
    -rm ./$@          # 删除

后续

这里是学习中遇到的或想到的问题,以下都是个人总结。

2024-08-31


问题:既然所有的代码都在父子进程中各自执行一次,那为什么子进程close后父进程还能写入数据?

回答和文件描述符中引用计数(f_count)有关, 当有文件被引用时文件描述会+1,关闭则会-1,只有当f_count = 0 时才会真正的关闭文件(释放)

Theme Jasmine by Kent Liao

本网站由 又拍云 提供CDN加速/云存储服务

鄂ICP备2023005457号    鄂公网安备 42011302000815号