IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 【UNIX】进程创建与进程控制相关系统调用函数 -> 正文阅读

[系统运维]【UNIX】进程创建与进程控制相关系统调用函数


Introduction

  本文主要讨论在UNIX系统如何通过一系列系统调用函数创建与控制进程,创建进程时用到的系统调用函数主要有:fork()、exec()、wait()等,控制进程用到的系统调用函数主要有:kill()等。下面结合代码详细介绍上述系统调用函数功能。


一、创建进程

  fork()可用于创建一个新的进程,更确切的说,它主要是用于在父进程中创建一个子进程,当调用此函数时,操作系统会为子进程分配其自己的地址空间、寄存器、PC等,子进程运行的代码是父进程代码的复制,但是执行不是从main函数开始,而是从fork()被调用的那行代码开始。fork()的返回值在父进程和子进程中也不一样,父进程中fork()的返回值为子进程的PID,而子进程中fork()的返回值为0.
  当调用fork()函数时,因为CPU调度器的复杂性,父进程和子进程的执行顺序其实是不确定的,此时可以使用wait()函数来控制两个进程的执行,使其执行顺序由不确定变为确定。调用wait()函数可以使执行延迟,直到子进程完成执行。
  除此之外,上面有提到fork()创建的子进程执行的代码是父进程的复制,如果要运行另一个程序可以调用exec()函数,当进程调用exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的main函数开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。使用上述fork()、wait()、exec()函数创建进程的实例代码如下所示:

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

int main(int argc, char *argv[]){
    printf("Hello world! (pid: %d)\n",(int) getpid());
    int rc = fork();
    if (rc<0) {
        printf("fork failed!");
    } else if (rc==0){
        printf("I'm child! (pid: %d)\n",(int) getpid());
        char *myargs[4];
        myargs[0] = strdup("./add_test");
        myargs[1] = strdup("1");
        myargs[2] = strdup("2");
        myargs[3] = NULL;
        execvp(myargs[0],myargs);
        printf("this shouldn't print out.\n");

    } else {
        int rc_wait = wait(NULL);
        printf("I'm father of %d (pid: %d)\n",rc,(int) getpid());
    }
}

  上述代码首先调用fork()创建子进程,在父进程分支中调用wait()控制执行顺序,等待子进程执行完后再执行父进程分支内容,子进程中调用了execvp()来执行另一个程序内容,execvp()是exec()函数的其中一个变种,详细解释可见exec函数族。上述子进程执行的程序add_test实现的功能为将终端输入的两个数相加并将结果打印出来,具体代码为:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]){
    int a,b,c;
    a = atoi(argv[1]);
    b = atoi(argv[2]);
    c = a+b;
    printf("the add result is: %d+%d=%d\n",a,b,c);
    return 0;
}

  将进程的创建分离为fork()和exec()函数,可以在fork()和exec()之间执行一些代码,这些代码可以改变即将运行的程序环境,从而可以轻松构建各种有趣的功能。shell主要就是调用fork、exec()和wait()实现它的功能;当你在shell里敲下命令的那一刻,shell首先在文件系统中搜索可执行文件的位置,调用fork()函数创建子进程,然后调用exec()函数的变种执行命令,同时调用wait()等待子进程完成运行,当子进程结束运行,shell返回打印prompt等待下一个命令。

二、控制进程

  在大多数UNIX shell中,不同的按键组合被设置成会向当前正在运行的进程传递特定的信号,比如说control-c发送SIGINT信号,control-z发送SIGTSTP信号。这个功能由信号子系统实现,信号子系统提供了丰富的基础设施向进程传递额外的事件,包括用单独的进程来接收和处理这些信号,以及发送信号给特定进程或者整个进程组的方式。对于进程来说,会使用signal()系统调用函数去捕获各种信号,这可以保证当给某个进程传递特定信号时,它会停止执行并运行一些特定的代码以响应这个信号。除此之外,还有专门的系统调用函数可以用来终止程序的运行:kill()。

  虽然fork()函数十分常用,但这也不意味着它没有问题,还有一个也可用于创建进程的函数是spawn(),使用时可以对比一下哪一个更为适用

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-02-06 14:09:05  更:2022-02-06 14:10:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 5:59:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码