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 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> C++笔记--Linux编程(10)-进程控制 fork系统调用 -> 正文阅读

[系统运维]C++笔记--Linux编程(10)-进程控制 fork系统调用

Linux进程模型

传统的Linux模型里有三种创建或者修改进程的操作

? ? ? ? 1.?system用于调用shell,执行一个指定的命令;

? ? ? ? 2. fork用于创建一个新的进程,该进程几乎是当前进程的一个完全拷贝;

? ? ? ? 3. exec可以在进程中用另外的程序来替换当前运行的进程

什么是进程

????????进程是一个正在执行的程序实例,他也是Linux基本的调度单位,一个进程由如下元素组成

????????进程的当前上下文(context),它是进程当前执行状态

????????进程的当前执行目录

????????进程访问的文件和目录

????????程序的访问权限

????????内存和其他分配给进程的系统资源

进程标识号

????????进程最知名的属性就是进程号(processID,PID)和它父进程号(parent processID,PPID)

????????PID和PPID都是非零的整数。 一个PID唯一标识一个进程。 一个进程创建的另一个新进程称为子进程。相反地,创建子进程的进程称为父进程。

????????所有进程追溯其祖先最终都会落到进程号为1的进程身上,这个进程叫init进程 Init进程是linux内核启动后第一个执行的进程。 Init引导系统,启动守护进程并且运行必要的程序。

进程PID和父进程PPID示例

创建多进程示例

#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"

int main () {

    pid_t pid;
    printf("start, pid=%d, ppid=%d\n", getpid(), getppid());

    int len = 4;

    for(int i=0; i<len; i++) {
        pid = fork();
        if(pid == 0) {
            printf("I am is child pid, pid=%d, ppid=%d\n", getpid(), getppid());
            break;
        } else if(pid > 0) {
            printf("I am is parent pid, pid=%d, ppid=%d\n", getpid(), getppid());
        }
    }

    sleep(4);
    printf("exit, pid=%d, ppid=%d\n", getpid(), getppid());
    while (1) {
        sleep(4);
    }

    return 0;
}

创建进程

system系统调用

#include <stdlib.h>
int system(const char *string);

system函数传递给/bin/sh –c 来执行string所指定的命令

string中可以包含选项和参数。

如果没有找到/bin/sh,函数返回127,如果出现其他错误返回-1,成功返回0,但如果string为NULL,返回一个非0值

示例

int main(void)
{
	printf(“%d\n”, system(“ls –l”));
	return EXIT_SUCCESS;
}

fork系统调用

#include <unistd.h>
pid_t fork(void);

pid_t fork(void); fork执行成功,向父进程返回子进程的PID,并向子进程返回0,这意味着fork即使只调用一次,也会返回两次

fork创建的新进程是和父进程(除了PID和PPID)一样的副本

父进程和子进程之间有点区别,子进程没有继承父进程的超时设置(使用alarm调用)、父进程创建的文件锁,或者未决信号

int main(void)
{
	pid_t child = fork();
	if(child == -1)
	{
		printf("call fork error\n");
		return -1;
	}
	if(child == 0)
	{
		printf("is child\n");
	}
	else
	{
		printf("child pid is %d\n",  child);
	}
	return 0;
}

你不能预计父进程是在它的子进程之前还是之后运行,它的执行是无序的,是异步的

fork的异步行为意味着你不应该在子进程中执行依赖与父进程的代码,反之亦然。

fork调用可能失败,原因是系统上已经运行了太多进程,已经超过了允许它执行的最大进程数。 fork执行失败,会向父进程返回-1,而且不创建子进程。

fork过程包括把父进程全部内存映像复制给子进程,这个过程很缓慢

UNIX的设计者创建了vfork调用,vfork调用也创建新进程,但它不产生父进程的副本。

Linux已经使用了写时复制技术,因此Linux的fork和UNIX的vfork一样快。

execve函数

int execve(const char *path, const char *arg, char * const envp[]);

fork创建了一个新的进程,产生一个新的PID。

execve用被执行的程序完全替换了调用进程的映像。

execve启动一个新程序,替换原有进程,所以被执行进程的PID不会改变。

execve函数接受三个参数。

????????path-要执行的文件完整路径;

????????argv-传递给程序完整参数列表,包括argv[0],它一般是执行程序的名字;

????????envp-是指向执行execed程序的环境指针,可以设为NULL。

示例

int main(void)
{
	char *args[] = { "/bin/ls", "-l", NULL };
	execve("/bin/ls", args, NULL);
	return 0;
}

wait和waitpid函数

wait和waitpid函数可以收集子进程的退出状态

#include <sys/wait.h>
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);

stauts保存子进程的退出状态

pid为等待进程的PID,它能接受下表列出的4种值中的一个

示例

wait函数示例

int main () {

    pid_t pid = fork();
    if(pid == 0) {
        printf("I am is child pid, pid=%d, ppid=%d\n", getpid(), getppid());
        sleep(2);
        return 0;
    } else if(pid > 0) {
        printf("I am is parent pid, pid=%d, ppid=%d\n", getpid(), getppid());
        int status;
        pid_t wpid = wait(&status);
        printf("wait ok wpid=%d, pid=%d\n", wpid, pid);
        if(WIFEXITED(status)) {
            printf("child exit with %d\n", WEXITSTATUS(status));
        } else if(WIFSIGNALED(status)) {
            printf("child kill with %d\n", WTERMSIG(status));
        }

    }

    return 0;
}

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章           查看所有文章
加:2021-08-02 11:10:24  更:2021-08-02 11:12:59 
 
开发: 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年5日历 -2024/5/9 21:31:53-

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