精华内容
下载资源
问答
  • 2021-05-10 06:46:33

    1.system()用于调用shell执行一个指定的命令去执行一个程序。

    int system(const char *string)

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

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

    如果没有找到/bin/sh,函数返回127如果出现其他错误返回-1,成功返回0,但是如果string为NULL,返回一个非零值。当前程序调用system()执行的程序没有任何关系。

    2.fork用户创建一个新的进程,该进程几乎是当前进程的一个完全拷贝。具体可参考

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

    0818b9ca8b590ca3270a3433284dd417.png

    #include

    #include

    #include

    int main(void) {

    puts("Hello World");/* prints Hello World */

    char *argv[] ={"ls","-l",NULL};

    execve("/bin/ls",argv,NULL);

    printf("end\n");

    return EXIT_SUCCESS;

    }

    printf(“end \n”);不会执行,可执行的代码,内存中变量代码数据被替换,操作系统分配的资源等没变。就好比家还是家,只是家里主人变了。

    更多相关内容
  • 1、创建进程 1.1 fork() 首先他是一个系统调用函数 作用:谁调用fork函数,调用成功之后,谁就创建出来一个子进程。 1.2fork()的返回值 创建成功: fork会返回两次在父进程中返回一次,在创建的子...

    目录

    1、创建子进程

    1.1 fork()

    1.2 fork()的返回值

    1.3、fork的原理

    1.4既然父子进程的代码是相同的,那么子进程是从哪行代码开始执行的? 

    1.5针对fork的返回值,让父子进程执行不一样的代码块(重点)

    2、僵尸进程&僵尸状态

    2.1什么是僵尸进程

     2.2我们模拟僵尸进程的状态

    2.3原因

    2.4僵尸进程的危害

    2.5僵尸进程的解决方案:

    2.6kill命令

    3、孤儿进程

    3.1什么是孤儿进程

    3.2模拟代码:

    3.3原因

    3.4孤儿进程的退出信息由谁回收呢?

    3.5孤儿进程有危害吗?


    • 1、创建子进程

      • 1.1 fork()

        • 首先他是一个系统调用函数
        • 作用:谁调用fork函数,调用成功之后,谁就创建出来一个子进程。
      • 1.2 fork()的返回值

        • 创建成功:(创建子进程成功之后他和父进程是抢占式执行的)
          • fork会返回两次在父进程中返回一次,在创建的子进程中返回一次。
          • >0返回给父进程(返回子进程的pid)
          • ==0返回给子进程
        • 创建失败:
          • 返回-1
      • 1.3、fork的原理

        • 子进程拷贝父进程的PCB        
        • 父子进程代码共享(父子进程拥有的代码是一样的)
        • 数据独有(各自有各自的进程地址空间)
        • 进程独立性:多个进程运行,需要独享各种资源,各自用有自己的进程地址空间,互相在执行的时候数据不会窜,互不干扰,即使两者的代码都一样。
      • 1.4既然父子进程的代码是相同的,那么子进程是从哪行代码开始执行的? 

        • 因为子进程是复制的父进程的PCB,此时父进程的PCB中程序计数器里保存的是fork执行的fork之后的下一条的汇编指令。所以子进程创建出来之后就会执行fork吓一条的命令。
      • 1.5针对fork的返回值,让父子进程执行不一样的代码块(重点)

        • 那我们为什么要创建子进程并且让父子进程执行不同代码呢?
          • 因为在某些场景中我们的代码可能会让程序崩溃,一旦程序崩溃就可能影响重大所以我们创建出来子进程让子进程帮我们来执行这些危险的代码,父进程可以不影响继续维持业务。
        • 那么正常启动的进程他的父进程是谁呢?
          • 我们可以看到父进程也有它的父进程        
          • 我们查看他的父进程,可以看到,他是由bash启动的,也就是说我们在终端中启动的进程都是由bash创建的子进程。

          • 所以我们就可以理解,bash为什么不执行我们写的代码呢?

          • 这是因为我们程序员写的代码可能有bug,可能会吧程序搞崩溃,所以就创建一个子进程来执行我们的代码。在我们启动程序时都要输入一个./mytest这里就是告诉bash我们的程序在哪里。通过./告诉我们的bash在当前目录。

    • 2、僵尸进程&僵尸状态

      • 2.1什么是僵尸进程

        • 子进程先于父进程退出, 子进程就会变成僵尸进程;
      •  2.2我们模拟僵尸进程的状态

      • 我们运行之后查看子进程状态,可以发现已经变成僵尸进程
      • 2.3原因

      • 子进程在退出的时候,会告知父进程 (信号:后续会涉及到),父进程忽略处理,父 进程并没有回收子进程的退出状态信息,也就是说:
        • 子进程在退出的时候,会告诉父进程
        • 父进程也收到了来自子进程的通知
        • 父进程时忽略处理(不处理)
        • 导致子进程的退出状态信息,一直没有得到回收
        • 所以子进程在内核当中的PCB一直没有回收
        • 所以子进程就变成了僵尸进程(子进程的状态就是僵尸进程)
      • 2.4僵尸进程的危害

      • 子进程的PCB没有被释放,导致内存泄漏。
      • 2.5僵尸进程的解决方案:

        • 杀死父进程:杀死父进程后僵尸进程就会变成孤儿进程,然后被一号进程领养,状态信息被一号进程回收(不推荐)
        • 重启操作系统,重启操作系统所有进程都会被杀死然后重新启动。(不推荐)
        • 父进程进行进程等待(推荐)
      • 2.6kill命令

        • 可以终止一个进程
        • kill [pid]:普通终止
          • 我们对父进程使用kill命令
          • 可以看到就是普通终止
          • kill -9 [pid]:强杀
          • 对父进程使用kill-9
          • 可以看到进程被杀死
          • 对僵尸进程使用kill命令
            • 可以看到kill命令无法终止僵尸进程
            • 对僵尸进程使用强杀,可以看到僵尸进程依然存在。
          • 总结:程序员对于僵尸进程是无法用kiil命令杀死的。
    • 3、孤儿进程

      • 3.1什么是孤儿进程

        • 父进程先于子进程退出, 子进程就会变成孤儿进程
      • 3.2模拟代码:

      • 没有孤儿状态! ! ( 切记)
        • 我们让子进程不退出然后让父进程
        • 让程序运行起来,我们可以发现在父进程还未退出的时候子进程的父进程的pid还是当前他的父进程,在他的父进程退出之后,子进程被1号进程领养。
        • 什么是一号进程?
        • 操作系统启动的第一个进程,后续有许多进程是由该进程创建出来的,或者是由该进程的子孙创建出来的,做操作系统初始化的一些工作,操作系统就是一个软件(一堆代码)。
        • 如果你试着运行这个代码你就会发现,在子进程打印的同时你还可以在bash命令行输入命令进行操作,这是因为,当我们查看他的进程状态,发现是一个S。
        • 我们要想结束孤儿进程的话直接找到孤儿进程的进程号杀死即可。
      • 3.3原因

      • 父进程先于子进程退出之后,既定回收子进程的父进程不在了,所以子 进程就变成孤儿了,所以称之为孤儿进程。
      • 3.4孤儿进程的退出信息由谁回收呢?

      • 由一号进程回收。
      • 3.5孤儿进程有危害吗?

      • 孤儿进程因为被1号进程收养所以没有危害。

    都看到这里了,不如点个赞再走吧,这对我真的很重要!!!

     

    展开全文
  • bash shell实现并发多进程操作前言目前我掌握的基本语言,php(最为熟悉,项目里代码都是用其实现),bash shell(运维利器),c(acm专用),这里面能实现多线程的貌似只有c,但是我c只是用来学习和实现算法和数据结构,...

    bash shell实现并发多进程操作

    前言

    目前我掌握的基本语言,php(最为熟悉,项目里代码都是用其实现),bash shell(运维利器),c(acm专用),这里面能实现多线程的貌似只有c,但是我c只是用来学习和实现算法和数据结构,因此工作中我想要模拟多进程并发操作,就只能依靠bash shell脚本了

    技能点

    shell脚本里实现并发操作,需要用到

    for循环

    &后台运行符

    wait等待所有子进程结束

    思路

    我们可以通过写一个for循环,控制每次需要批量操作的次数,

    然后封装一个方法,方法里进行批量操作,并将此方法用&符号放在后台运行

    每个循环结束前用wait函数,确保当前批量处理操作全部完成

    示例

    我们准备批量的执行创建目录操作,目录名称为数字,从1开始到100,每次批量创建20个

    无并发时

    代码如下:

    [html]

    #!/bin/bash

    #开始时间

    begin=$(date +%s)

    #测试根目录

    root_dir="/home/wzy/wzy_scripts/file_scripts/test"

    if [ ! -d $root_dir ]; then

    mkdir -p $root_dir

    fi

    cd $root_dir

    #循环创建10000个目录

    for ((i=0; i<10000; ))

    do

    mkdir $i

    i=$(expr $i + 1)

    done

    #结束时间

    end=$(date +%s)

    spend=$(expr $end - $begin)

    echo "花费时间为$spend秒"

    运行时间:

    47541366251571.png

    并发操作

    我们每次并发创建200个目录,因此循环执行50次即可实现创建10000个目录的工作

    代码如下:

    [html]

    #!/bin/bash

    #开始时间

    begin=$(date +%s)

    #测试根目录

    root_dir="/home/wzy/wzy_scripts/file_scripts/test"

    if [ ! -d $root_dir ]; then

    mkdir -p $root_dir

    fi

    cd $root_dir

    #批量创建目录函数

    function create_dir()

    {

    mkdir $1

    }

    #循环创建10000个目录

    count=10000

    rsnum=200

    cishu=$(expr $count / $rsnum)

    for ((i=0; i

    do

    start_num=$(expr $i \* $rsnum + $i)

    end_num=$(expr $start_num + $rsnum)

    for j in `seq $start_num $end_num`

    do

    create_dir $j &

    done

    wait

    i=$(expr $i + 1)

    done

    #结束时间

    end=$(date +%s)

    spend=$(expr $end - $begin)

    echo "花费时间为$spend秒"

    主要是分页处理和&以及wait的使用

    运行时间:

    68111366251572.png

    总结

    通过&、wait和for循环来进行并发操作能显著的提高效率,大家可以参考这个方法用在自己的日常工作中,我是在创建多个mysql库的时候掌握了这个方法!

    展开全文
  • 创建进程:fork() 暂缓进程执行:sleep() 1.fork()函数 1.使用方法: #include <unistd.h> pid_t fork(void); 2.函数功能: 函数执行后,系统会创建一个原进程几乎相同的进程,之后父子进程都继续...

    两个函数

    创建进程:fork()
    暂缓进程执行:sleep()

    1.fork()函数

    1.使用方法:

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

    2.函数功能:
    函数执行后,系统会创建一个与原进程几乎相同的进程,之后父子进程都继续执行。子进程创建成功后,原程序会被复制,就有了两个fork函数。若子进程创建失败,原程序不会复制。
    3.返回值:
    成功:返回两个值:

    1. 父进程的fork函数会返回子进程的pid,
    2. 子进程的fork函数会返回0。

    不成功:只有父进程的fork函数返回-1。
    Eg.1.创建单个子进程
    使用fork函数创建一个进程,创建成功后父子进程分别执行不同的功能。

    test_fork.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    int main(){
    	pid_t tempPid;
    	tempPid = fork();
    	if(tempPid == -1){
    		perror("fork error");
    	}else if(tempPid > 0){//parent
    		printf("parent process, pid = %d, chilpid = %d\n", getpid(), tempPid);
    	}else{//child
    		printf("child process, pid = %d, ppid = %d\n", getpid(), getppid());
    	}//of if
    	printf("......finish......");
    	return 0;
    }//of main
    

    补充说明:
    getpid()返回值为调用getpid()进程的PID,而getppid()返回调用这个函数进程的父进程的PID

    执行结果:
    在这里插入图片描述
    在这里插入图片描述
    Question1:
    ?两次执行,结果不同:一个是先调用父进程,一个是先调用子进程
    因为两进程优先级相同,两进程同时抢资源,所以执行顺序可能不同。
    在这里插入图片描述

    Question2:
    ?发现子进程的ppid并不等于父进程的pid
    我们可以先来看一下1412是个什么东西
    在这里插入图片描述
    /usr/lib/systemd/system目录自动存放启动文件的配置位置
    而老师上课的时候提到了init,说会被init进行领养,下面问题变成孤儿进程为什么不是被init领养
    在这里插入图片描述
    在Ubuntu20.04中:
    在这里插入图片描述
    所以归根结底还是init领养了子进程

    fork()创建子进程后,在两进程抢夺资源的时候,父进程先于子进程被调用,然后父进程被摧毁,子进程接着被调用,但是父进程已经被摧毁,子进程变为孤儿进程,init会“收养”这个子进程所以该子进程的父进程就变为了init。
    我们可以和图一进行对比,发现虽然两次运行都是父进程先运行,但是第一次子进程运行的时候父进程并没有结束运行,所以子进程的父进程显示的还是我们的父进程而不是init。

    为了防止子进程变为孤儿进程,可以使父进程后于子进程执行,即让父进程等待子进程执行结束后再执行。
    此处我们用到sleep()函数:此处我们先卖个关子,在第二点进行详细案例说明。
    我们创建了一个子进程,那么要想通过父进程创建多个子进程又该怎么办呢?

    Eg.2.创建多个子进程

    int i;
    for(i = 0; i < 2; i ++){
    	tempPid = fork();
    }//of for i
    

    执行结果:
    在这里插入图片描述

    此时会发现创建进程数量与预计的不同,产生了4个进程并且两个父进程,两个子进程。

    父进程在创建子进程的同时,之前创建的子进程也会调用fork函数进行子进程的创建,成为了之后创建的进程的父进程,如果只想父进程才进行子进程的创建的话,必须进行判断:如果是父进程才能创建子进程。
    改进版:Eg.2.创建多个子进程

    test_fork2.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    int main(){
    	pid_t tempPid;
    	int i;
    	for(i = 0; i < 2; i ++){
    		if((tempPid = fork()) == 0){
    			break;
    		}//of if
    	}//of for i
    	if(tempPid == -1){
    		perror("fork error");
    	}else if(tempPid > 0){//parent
    		printf("parent process, pid = %d, ppid = %d\n", getpid(), getppid());
    	}else{//child
    		printf("I am child process = %d, pid = %d, ppid = %d\n", i + 1, getpid(), getppid());
    	}//of if
    	printf("......finish......");
    	return 0;
    }//of main
    

    执行结果:
    在这里插入图片描述

    2.sleep()函数

    函数功能:
    暂缓进程执行
    Eg.1.父进程回收全部子进程

    test_fork3.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    int main(){
    	pid_t tempPid;
    	int i;
    	for(i = 0; i < 2; i ++){
    		if((tempPid = fork()) == 0){
    			break;
    		}//of if
    	}//of for i
    	if(tempPid == -1){
    		perror("fork error");
    	}else if(tempPid > 0){//parent
    		printf("parent process, pid = %d, ppid = %d\n", getpid(), getppid());
    		sleep(2);
    	}else{//child
    	 	sleep(i);
    		printf("I am child process = %d, pid = %d, ppid = %d\n", i + 1, getpid(), getppid());
    	}//of if
    	printf("......finish......");
    	return 0;
    }//of main
    

    运行结果:
    在这里插入图片描述
    完美解决了孤儿进程的问题。
    补充:
    僵尸进程:

    僵尸进程是当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸进程。僵尸进程会占用进程号。
    下面摘自百度百科:
    由于子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束。但UNⅨ提供了一种机制可以保证只要父进程想知道子进程结束时的状态信息, 就可以得到。这种机制就是: 在每个进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等。但是仍然为其保留一定的信息(包括进程号the process ID,退出状态the termination status of the process,运行时间the amount of CPU time taken by the process等)。直到父进程通过wait / waitpid来取时才释放. 但这样就导致了问题,如果进程不调用wait / waitpid的话,那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵尸进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免。

    展开全文
  • 由于这个过程进程继承了父进程几乎所有的东西,我们一般希望子进程进程不一样的事情,所以一般fork()都搭配着exec()来使用,替换掉子进程的数据和指令,从而达到改变子进程行为的目的 Linux系统调用sys_...
  • 例如,进程可以创建一个子进程来执行特定的任务,然后调用诸如 wait() 这样的一些库函数检查子进程是否终止。如果子进程已经终止,那么,它的终止代号将告诉父进程这个任务是否已成功地完成。 为了遵循这些设计原则...
  • 我们希望脚本可以执行多个任务,支持多进程,且前面的任务不会影响其他任务的工作路径而且当一个任务exit时不会exit所有的任务。 我们可以将每一个任务封装成bash的function,然后通过命令行参数运行这些function。
  • bash脚本运行为守护进程 setsid myscript.sh >/dev/null 2>&1 < /dev/null &
  • Linux c/c++之进程创建

    千次阅读 2022-03-04 21:10:08
    待被创建进程执行结束之后当前进程继续执行 #include <stdio.h> #include <unistd.h> #include <stdlib.h> int main(){ printf("先休息再工作\n"); sleep(5); for (int i = 0; i < 5; ++...
  • 进程创建进程在执行过程中可能创建多个新的进程。创建进程称为父进程,而新的进程称为子进程。每个新进程可以再创建其他进程,从而形成进程树。大多数的操作系统(包括 UNIX、Linux 和 Windows)对进程的识别采用的是...
  • Linux shell实现多进程进程池)

    千次阅读 2021-11-11 14:59:56
    Linux shell实现多进程进程池) 最近有个需求要批量下载一堆文件,给了一个txt文本,里面每一行都是一个文件的下载地址,样式如下: img.txt http://www.test.com/download/a.zip ...... 于是最开始我写个脚本直接...
  • Linux进程管理---用代码创建进程(fork函数)

    多人点赞 热门讨论 2022-05-04 10:13:49
    对进程创建的理解(1)创建进程的两种方法(2)对创建进程的理解PCB和代码数据4.fork的返回值 1.fork函数概念 fork函数在代码中创建进程的一个系统调用接口,它可以为进程创建子进程。 我们可以使用man手册来查询一下...
  • bash脚本提交后台运行For example, I want to spawn many ssh background processes in one bash script: 例如,我想在一个bash 脚本中生成许多ssh后台进程: for i in `cat ./all-hosts` do ssh $i "ifconfig | ...
  • 操作系统-15-进程创建

    千次阅读 2021-04-14 11:50:35
    从这一节起,我们将详细讲解进程的一生。进程如人生,进程的一生同样包含三个阶段,创建,运行和终结,本节是进程...1,操作系统创建进程:初始化 作为计算机的Boss,最初的进程是由操作系统创建的,操作系统在初始化的
  • linux上的bash和Windows中的命令行有很大的不同。但是两者都有完成相似任务的命令,比如Linux上bash的ls命令的功能,类似于Windows命令行中的dir命令的功能。用C语言写一个简单的Linux终端软件,接收用户发出的类似...
  • 作为一个非常简单的实现,取决于bash的新版本足够等待-n(等待只有下一个作业退出,而不是等待所有作业):#!/bin/bash# ^^^^ - NOT /bin/sh!num_procs=$1num_iters=$2for ((i=0; iwhile read -r -a curr_jobs < &...
  • 今天介绍进程进程的管理,子进程创建以及进程资源的回收 首先什么是进程? 答:进程是程序的实例。程序是静态的,是存放在硬盘上的,程序运行起来就形成了进程。程序从磁盘到内存里之后就形成了进程进程又分为...
  • Bash 实用程序守护进程监视文件更改并对其进行转换。 动机 在更改时重新编译代码包或从一种语言转换为另一种语言是常见的任务。 例如: JSX 转 JS 咖啡脚本到 JS flac 转 mp3、aac 等 png 到 webp、jpeg2000、...
  • 例如子进程从fork返回后,调用exec*函数(进程替换马上详谈) fork调用失败的原因 众所周知,创建进程成本很高(时间+空间),系统中有太多进程时,资源不足 用户创建的进程数超出了限制,为了防止某些用户恶意创建。...
  • 实验二 进程创建

    千次阅读 2019-11-07 22:00:31
    实验二进程创建 一、实验目的 1.加深对进程概念的理解,明确进程和程序的区别。 2.掌握进程创建方法 二、实验学时 2学时 三、实验内容 1.ps命令的使用(请将使用的命令和结果写在实验报告册中) (1)显示所有...
  • Linux进程编程实践——进程概念、进程... Linux下的进程描述——task_struct二、fork创建进程2.1 获取进程标识符查看进程Q1:为什么要知道一个进程的PID以及它父进程的PID呢?2.2 fork创建进程Q1:如何理解进程创建?Q
  • bash:4.3.42(1)-发行版(x86_64-pc-linux-gnu)执行以下脚本:# This is myscript.shline=$(ps aux | grep [m]yscript) # A => returns two duplicates processes (why?)echo"'$line'"ps aux | grep [m]yscript # ...
  • 我有一个bash脚本创建ssh隧道来安全地连接远程mysql服务器,如下所示.ssh -f -N -L $LOCAL_PORT:localhost:3306 $REMOTE_USER@$REMOTE_IPmysql -P $LOCAL_PORT -h 127.0.0.1 -u lapl_stg -p${REMOTE_DB_PASS} <...
  • Bash编程】之 协作进程coproc

    千次阅读 2019-03-04 19:10:40
    shell中的协作进程coprocess是指...”一样,不同的是,协作进程与其父进程间有双向的管道,提供了一种便利的通信途径。 协作进程命令格式如下: coproc [NAME] command [redirections] 上述命令用于创建一个名为N...
  • 提问: 我想要知道运行中脚本子shell的进程id。我该如何在shell脚本中得到PID。 当我在执行shell脚本时,它会启动一个叫子shell的进程...在bash中,子shell进程的PID存储在一个特殊的变量‘$$’中。这个变量只读,你不可
  • 18-用fork函数创建进程

    千次阅读 多人点赞 2018-09-05 14:29:02
    1. 程序和进程   简单来说,程序是一组存储在磁盘的机器语言指令集合(本质上是一个...  如果同一个程序多次运行,每次都在内存中创建出不同的进程,每个进程都有自己的代码空间和数据空间,且进程间彼此独立,...
  • Linux下理解进程,fork()创建进程

    万次阅读 2018-04-21 23:42:53
    进程初认识 进程的概念(比较抽象):程序运行的实体  作为资源分配的基本单元 进程的理解:什么是进程     //hello.c #include &lt;stdio.h&gt; ...
  • 会话首进程:该会话运行的第一个进程bash)(用该bash的PID来标识该会话(id)) 进程组:每运行一个命令,就是一个进程组(进程组的id是该命令的PID或父进程的PID(父子进程)) 组长进程:父子进程中父进程为组长进程 ...
  • 此时我们的子进程就可以读取到父进程的数据了,这就是管道的作用过程 三、管道创建函数pipe 实际上Linux给我们提供了创建管道的函数pipe,pipe函数正是基于“子进程会继承父进程的资源”这种特性来实现的,因为子...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 137,949
精华内容 55,179
关键字:

创建的进程与bash进程