精华内容
下载资源
问答
  • 进程的创建与控制

    2020-06-16 12:38:53
    内核创建一个init进程,内核不提供直接创建新进程的系统调用 所有进程都由init进程通过fork机制创建。 子进程可以重父进程那继承所有... idle 调度进程 , 不执行任何磁盘上的文件, 唯一个没有调用fork的进程 pid ..

    内核创建一个init进程,内核不提供直接创建新进程的系统调用  所有进程都由init进程通过fork机制创建。
    子进程可以重父进程那继承所有东西
    调用fork后, linux会重新开辟以块内存空间, 复制一份老进程的数据到新的内存空间。
    进程的标识 : 操作系统会为每个进程分一个唯一的整数ID, 非负整数 pid, pid范围0-32767
    ps -A  列出进程的ID号
    pid = 0的进程 是系统中所有进程的祖先。 idle 调度进程 , 不执行任何磁盘上的文件, 唯一个没有调用fork的进程
    pid = 1的进程 是init进程, 系统启动过程中由pid = 0创建。系统启动后, init变为守护进程,检测其他进程
    除了了init, 任何其他进程都有一个ppid表示父进程的ID,  pgid 进程组号
    linux 进程是树结构

    getpid() getppid() getpgid()

    #include <sys/types.h>
    #include <unistd.h>


    pid_t getpid(void)  获取本进程号
    pid_t getppid(void) 获取此函数的父进程号
    pid_t getpgid(pid_t pid)  获取本进程的组号, 传入进程ID  参数为0 返回当前进程的进程组号

    #include <sys/types.h>
    #include <stdio.h>
    #include <unistd.h>
    int main(int argc, char *argv[]){
      pid_t pid, ppid, pgid
      pid = getpid();
      prinf("pid = %d\n", pid);
      ppid = getppid();
      printf("pid = %d\n", ppid);
      pgid = getpgid(pid);
      printf("pgid = %d\n", pgid);
      return 0;
    }

    gcc getpid.c -o getpid -Wall
    ./getpid
    cc getpid.c 
    ./a.out

    pid_t fork() 
    进程由,代码段, 数据段, 堆栈段
    调用fork函数可以创建,启动一个新进程。 新进程和父进程共享代码段, 复制了数据段和堆栈段,  刚创建的进程跟父进程机会一摸一样,就pid不一样
    fork会向父进程,子进程各有一个返回值。     返回子进程的进程号给父进程,给子进程的返回值是0. 返回值是-1 没有创建成功,调用失败
    fork() 函数调用一次, 返回2次,
    x =  fork()
    if (x == 0){
      子进程
    }else(x > 0){
      父进程
    }else{
      创建失败
    }

    #include <unistd.h>
    #include <stdio.h>
    #include <errno.h>
    #include <stdlib.h>
    int main(){
      pid_t pid;
      int x = 1;
      pid = fork();
      if(pid == 0){
        printf("child : x = %d\n", ++x);
        exit(0);
      }
      printf("parent: x = %d\n", --x);
      exit(0);
    }

    父进程和子进程是并发执行的。内核可以任何方式交替执行, 程序的执行结果在不同的系统中可能不同, 父子进程是相同的但是独立的地址空间。
    父子进程都把结果输出到屏幕上, 子进程继承了父进程的所有打开文件。

    子进程执行函数exec(), 通过指定路径, 文件名并找到一个可执行文件。 一旦执行就替代了原进程的代码, 废除了原进程的数据段和堆栈堆栈段, 但是进程号是原进程。
    exec()执行成功后没有返回值, 调用失败返回-1

    #include <sys/types.h>
    #include <sys/wait.h>
    #include <unistd.h>
    #include <stdio.h>
    int main(){
      pid_t pid;
      pid = fork();
      if(pid < 0)
        printf("error in fork!");
      else if(pid == 0){
        printf("I am the child process Id is %d\n", getpid());
      }else {
        printf("I am the parent process Id is %d\n", getpid());
      }
    }
    vfork()函数创建进程,  返回值正确时跟fork一样, 创建失败返回-1
    用vfork()函数创建进程, 通常使用exec()紧跟其后,  并不完全复制父进程的数据区,  vfork()调用后, 子进程先运行, 父进程挂起, 直到子进程调用完exec或者退出函数exit()之后,父子进程执行顺序才不受限制
    如果调用exec或者exit之前父进程被激活, 就会出现死锁。

    展开全文
  • 进程

    2019-10-11 15:49:13
    3.Linux系统中进程由以下三部分组成:①进程控制块PCB;②数据段;③正文段 4.进程关系: 父子关系,兄弟关系 , 亲戚关系 5.进程的状态以及转换:运行,就绪,阻塞 6.僵尸进程:子进程已经结束,但是父进程并没有...

    1.运行的程序就称为进程
    2.进程的特征:动态性,并发行,独立性 , 异步性
    3.Linux系统中进程由以下三部分组成:①进程控制块PCB;②数据段;③正文段
    4.进程关系: 父子关系,兄弟关系 , 亲戚关系
    5.进程的状态以及转换:运行,就绪,阻塞
    6.僵尸进程:子进程已经结束,但是父进程并没有回收其资源,此时的子进程就是一个僵尸进程。使用wait和waitpid函数可以解决这个问题
    7.孤儿进程:父进程已经结束,但是子进程仍在运行。这时候子进程就是孤儿进程
    8.守护进程:一种脱离终端,在后台运行的一种进程。终端的开关与他无关
    9.创建进程
    分配id,分配PCB
    分配地址空间
    拷贝父进程的进程空间
    将子进程置为就绪状态
    放到就绪队列
    10.程序转换为进程
    内核将程序读入内存,为程序分配内存空间
    内核为该进程分配进程标识符pid和其他所需资源
    内核为该进程保存PID及相应的状态信息,把进程放到运行队列中等待执行.程序转化为进程后就可以被操作系统的调度程序调度执行了
    11.销毁进程
    回收各种资源
    记录系统日志
    将进程换出内存,置为僵尸状态
     转存储调度

    展开全文
  • Linux进程学习笔记

    2019-11-04 21:09:03
    一个进程只能对应一个程序,一个程序却可以对应多个进程,没有建立进程的程序不能作为一个独立的单位获得操作系统的认可; (2)、进程控制块(PCB) 每个进程在内核中都有一个进程控制块来维护进程的相关信息,linux...

    进程与线程

    1、进程的相关概念

    (1)、进程与程序:

    1. 进程是动态的,程序是静态的;
    2. 进程有生命周期,程序没有生命周期;
    3. 一个进程只能对应一个程序,一个程序却可以对应多个进程,没有建立进程的程序不能作为一个独立的单位获得操作系统的认可;

    (2)、进程控制块(PCB)

    每个进程在内核中都有一个进程控制块来维护进程的相关信息,linux内核的进程控制块是task-struct结构体。内部成员很多,主要有:

    • 进程ID:系统中每个进程都有唯一的id,用pid_t类型表示。
    • 进程状态:有初始、就绪、运行、挂起、终止五个状态。
    • 进程切换需要保存和恢复的CPU寄存器。
    • 描述虚拟地址空间的信息。
    • 描述控制终端的信息。
    • 当前工作目录。
    • 文件描述符表:包含很多指向file结构体的指针。
    • 和信号相关的信息。
    • 用户组id和组id。
    • 会话(session)和进程组。
    • umask掩码。
    • 进程可以使用的资源上限。

    2、进程控制

    (1)、fork函数

    pid_t fork(void)
    

    问题:

    1. fork函数的返回值?
      答:当fork函数创建子进程成功后,会返回两个,一个数为0:代表子进程的返回值;当返回值大于0时:父进程返回值,代表子进程的id。

    2. 子进程创建成功后,代码的执行位置?
      答:父进程执行到哪,子进程就从哪里开始执行。

    3. 父子进程的执行顺序?
      答:随机执行,谁先抢到cpu,谁先执行。

    4. 如何区分父子进程?
      答:通过fork函数的返回值

    // 通过判断for循环的打印结果即可知道问题b与问题c答案
    #include <stdio.h>   
    #include <stdlib.h>    
    #include <unistd.h>
    #include <sys/types.h>  
    #include <sys/stat.h>  
    int main(int argc,const char* argv[])
    {
        pid_t pid;
        for(int i=0;i<4;i++)
        {
            printf("----i-----=%d\n",i);
        }
        pid = fork();
        //父进程
        if(pid>0)
        {
            printf("parent process,pid=%d"\n",getpid());
        }
        // 子进程
        else if(pid == 0)
        {
            printf("child process,pid=%d,ppid=%d\n"\n",getpid(),getppid());
        }
        for(int i=0;i<4;i++)
        {
            printf("i=%d\n",i);
        }
        return 0;
    }
    

    父子进程之间的关系

    (2)、循环创建多个子进程

    #include <stdio.h>   
    #include <stdlib.h>    
    #include <unistd.h>
    #include <sys/types.h>  
    #include <sys/stat.h>  
    int main(int argc,const char* argv[])
    {
        int number=3;//要创建的子进程个数
        pid_t pid;
        for(int i=0;i<number;i++)
        {
            pid = fork();
            if(pid==0)//子进程不再进程fork()
            {
                break}
        }
        //如何判断是第几个孩子
        if(i==0)
        {
            printf("first process,pid=%d\n",getpid());
        }
        if(i==1)
        {
            printf("second process,pid=%d\n",getpid());
        }
        if(i==2)
        {
            printf("third process,pid=%d\n",getpid());
        }
        if(i==number)
        {
            printf("father process,pid=%d\n",getpid());
        }
        return 0;
    }
    
    

    2、进程相关命令

    1、查询某个进程的id

    ps aux | grep XXX
    ps ajx | grep XXX
    

    2、kill 向指定的进程发送信号
    查看信号:

    kill -l
    

    杀死某个进程:

    kill -9(SIGKILL) pid
    

    3、进程之间的数据共享

    父子进程之间的数据:
    读时共享,写时复制。
    在这里插入图片描述

    4、exec函数蔟

    • (1)、exec函数:
      • 让父子进程执行不相干的操作;
      • 能够替换进程地址空间中的源代码.txt段;
      • 在当前程序中调用另外一个程序;
        • 在执行exec之前需要fork();
      • 返回值:
        • 如果函数执行成功,不返回;
        • 如果执行失败,打印错误信息,退出当前进程;
    • (2)、执行指定目录下的程序:
      int execl(cnst char* path,const char* arg,...)
      • path:要执行的程序的绝对路径;
      • 变参arg:要执行的程序所需要的参数;
      • 第一arg:占位;
      • 后边的arg:命令的参数;
      • 参数写完以后:NULL;
      • 一般执行自己写的程序;
    #include <stdio.h>   
    #include <stdlib.h>    
    #include <unistd.h>
    #include <sys/types.h>  
    #include <sys/stat.h>  
    int main(int argc,const char* argv[])
    {
        
        pid_t pid = fork();
        for(int i=0;i<4;i++)
        {   
            printf("it is parent process\n");
        }
        //子进程执行ls命令
        if(pid==0)
        {   
            execl("/bin/ls","ls","-l",NULL);
        }
        //运行程序后,会发现下面的代码只有父进程打印了
        for(int i=0;i<4;i++)
        {   
            printf("=====it is parent process====\n");
        }
        return 0;
    }
    
    
    • (3)、执行PATH环境变量能够搜索到的程序:
      int execlp(cnst char *file,const char *arg,...)
      • file:要执行的命令的位置
      • 变参arg:要执行的程序所需要的参数
      • 第一arg:占位
      • 后边的arg:命令的参数
      • 参数写完以后:NULL
      • 执行系统自带的程序
        #include <stdio.h>   
        #include <stdlib.h>    
        #include <unistd.h>
        #include <sys/types.h>  
        #include <sys/stat.h>  
        int main(int argc,const char* argv[])
        {
            pid_t pid = fork();
            for(int i=0;i<4;i++)
            {   
                printf("it is parent process\n");
            }
            //子进程执行ps命令
            if(pid==0)
            {   //这里不需要指定路径,系统会在PATH中找到该命令
                int ret = execlp("ps","ps","aux",NULL);.
                perror("Execlp:");//如果execlp执行错误(返回-1),系统才会执行该代码。(所以可以不写ret)
                exit(1);
            }
            //运行程序后,会发现下面的代码只有父进程打印了
            for(int i=0;i<4;i++)
            {   
                printf("=====it is parent process====\n");
            }
            return 0;
        }
    
    

    5、进程回收

    1. 孤儿进程

    • 爹生孩子;
    • 爹先死,孩子还活着,孩子叫孤儿进程;
    • 孤儿被init进程领养,init进程变为孤儿进程的父亲;
    • 为了释放子进程占用的系统资源;
      • 进程结束后,能够释放用户去空间;
      • 释放不了pcb,必须由父进程释放;
    #include <stdio.h>   
    #include <stdlib.h>    
    #include <unistd.h>
    #include <sys/types.h>  
    #include <sys/stat.h>  
    int main(int argc,const char* argv[])
    {
        pid_t pid = fork();
        if(pid==0)
        {
            sleep(1);//子进程睡一秒,保证父进程先死
            printf("child pid = %d,ppid = %d\n",getpid(),getppid());
        }
        else if(pid > 0)
        {
            printf("==========parent process==========");
            printf("parent pid = %d,ppid = %d\n",getpid(),getppid());
        }
        // 可以看到,程序运行完以后,两个parent pid不一样,因为父亲先挂,子进程被干爹init进程收养
        return 0;
    }
    

    2. 僵尸进程

    • 孩子死了,爹还活着,爹不去释放子进程的pcb,孩子变为僵尸进程;
    #include <stdio.h>   
    #include <stdlib.h>    
    #include <unistd.h>
    #include <sys/types.h>  
    #include <sys/stat.h>  
    int main(int argc,const char* argv[])
    {
        pid_t pid = fork();
        if(pid==0)
        {
            printf("child pid = %d,ppid = %d\n",getpid(),getppid());
        }
        else if(pid > 0)
        {   //父进程死循环,子进程挂掉后,父进程没办法去回收子进程pcb,孩子变为僵尸进程
            while(1)
            {
                printf("==========parent process==========");
                printf("parent pid = %d,ppid = %d\n",getpid(),getppid());
            }
        }
        // 假设程序名字为app,则执行完以后 去查 ps aux | grep app,可以看到有个app的状态为Z+(zombie:僵尸)
        return 0;
    }
    

    僵尸进程
    3. 进程回收
    编程过程中,有时需要让一个进程等待另一个进程,最常见的是父进程等待自己的子进程,或者父进程回收自己的子进程资源包括僵尸进程。

    • (1)、wait(阻塞函数)
      • pid_t wait(int *status);
        • 头文件:
          • #include <sys/types.h> /* 提供类型pid_t的定义*/
          • #include <wait.h>
        • 函数作用:
          1. 阻塞并等待子进程退出;
          2. 回收子进程残留资源;
          3. 回去子进程结束的原因;
        • 返回值:
          • -1:回收失败:已经没有子进程了;
          • >0:回收的子进程对应的的pid;
        • 参数:status,子进程的退出状态
          • 判断子进程是如何挂掉的(需要四个宏)
          1. WIFEXITED(status):是否正常退出,如果该宏为真,则使用下面这个宏可以获取进程退出的状态(exit/return)的参数;
            WEXITSTATUS(status);
          2. WIFSIGNALED(status):是否被某个信号杀死,如果该宏结果为非零,则使用下面的宏可以取得使进程终结的那个信号的编号
            WTERMSIG(status);
        • 调用一次wait函数,只能回收一个子进程;
    #include <stdio.h>   
    #include <stdlib.h>    
    #include <unistd.h>
    #include <sys/types.h>  
    #include <sys/stat.h>  
    #include <wait.h>
    int main(int argc,const char* argv[])
    {
        pid_t pid = fork();
        if(pid >0)//父进程回收子进程
        {
            printf("parent process,pid = %d,ppid = %d\n",getpid(),getpid());
            int status;
            pit_t wpid = wait(&status); 
            //判断是否是正常退出的
            if(WIFEXITED(status))
            {   // 打印退出状态参数
                printf("exit value:%d\n",WEXITSTATUS(status));
            }
            //判断是否是被信号杀死的
            if(WIFEXITED(status))
            {   // 查看是被那个信号杀死的
                printf("killed   by signal:%d\n",WTEMSIG(status));
            }
            printf("died child pid = %d\n",wpid);
        }
        else if
        {
            sleep(2);
            printf("child process,pid = %d,ppid = %d\n",getpid(),getpid());
        }
        return 0;
    }
    
    • (2)、 waitpid
      • pid_t waitpid(pid_t pid,int *status,int options);
        • 头文件:
          • #include <sys/types.h> /* 提供类型pid_t的定义*/
          • #include <wait.h>
        • 函数作用:
          • 同wait函数;
        • 返回值:
          • -1:回收失败:已经没有子进程了;
          • >0:回收的子进程对应的的pid;
          • =0:参数3为WNOHANG,且子进程正在运行;
        • 参数:
          1. pid:
            1. pid==-1:等待任一个子进程,与wait函数等效;
            2. pid>0:等待其的进程ID与pid相等的子进程;
            3. pid==0:等待其组ID等于调用进程的组ID的任一子进程;
            4. pid<-1:等待其组ID等于pid的绝对值的任一子进程;
          2. status:子进程的退出状态,用法同wait函数;
          3. options:设置为WNOHANG,函数为非阻塞,设置为0,函数阻塞;
            0:参数3为WNOHANG,且子进程正在运行;
        • 参数:
          1. pid:
            1. pid==-1:等待任一个子进程,与wait函数等效;
            2. pid>0:等待其的进程ID与pid相等的子进程;
            3. pid==0:等待其组ID等于调用进程的组ID的任一子进程;
            4. pid<-1:等待其组ID等于pid的绝对值的任一子进程;
          2. status:子进程的退出状态,用法同wait函数;
          3. options:设置为WNOHANG,函数为非阻塞,设置为0,函数阻塞;
        • 调用一次wait函数,只能回收一个子进程。可以选择回收那个子进程;
    展开全文
  • python fork子进程()

    千次阅读 2016-09-01 15:21:32
    fork是个好动西,它通过系统调用能够创建出一个与原来进程一模一样的进程,子进程可以执行和父进程一样的代码,通过逻辑控制,也可以让父进程和子进程执行完全不同的代码。如此好用的东西,windows是没有的,所以...

        fork是个好动西,它通过系统调用能够创建出一个与原来进程一模一样的进程,子进程可以执行和父进程一样的代码,通过逻辑控制,也可以让父进程和子进程执行完全不同的代码块。如此好用的东西,windows是没有的,所以,赶紧转到linux吧!

    一、初识fork

        创建子进程的过程非常简单

    pid=os.fork()
        返回值有三种

        (1) pid < 0  表示创建失败

        (2) pid = 0   此时,处在子进程中

        (3) pid > 0  此时,处在父进程中  pid 的值就是刚刚创建出来的子进程的pid

    二、 第一个简单示例

        下面看一段简单的代码:

    def create_child():
        pid0=os.getpid()
        print '主进程',pid0
    
        try:
            pid1=os.fork()
        except OSError:
            print u'你的系统不支持fork'
            exit()
    
        if pid1 <0:
            print u'创建子进程失败'
        elif pid1==0:
            print '子进程 ',pid1,os.getpid(),os.getppid()
        else:
            print '主进程 ',pid1,os.getpid(),os.getppid()
    
        print u'这句话,父进程和子进程都会执行'

        如果fork函数执行成功,那么从第11行开始的代码,父进程和子进程都会执行,此时,他们已经是两个完全不相干的进程了。

    三、父子内存关系

        对于fork,有一点必须搞清楚,那就是原来父进程里的那些变量和子进程里的变量是什么关系。一种普遍的存在误区的理解是子进程完全拷贝了父进程的数据段、栈和堆上的内容,但实际情况是linux引入了写时拷贝技术,子进程的页表项只想了与父进程相同的物理内存页,这样只拷贝父进程的页表项就可以了,这些页面被标记为只读,如果父子进程都不去修改内存内容,大家相安无事,一旦父子进程中的某一个尝试修改,就会引发缺页异常。此时,内核会尝试为该页面创建一个新的物理页面,并将内容真实的复制到物理页面中,这样,父子页面就各自拥有了各自的物理内存。

        看下面这段代码:

    class TestFork():
        def __init__(self,age):
            self.age = age
    tf = TestFork(10)
    def child_work():
        tf.age = os.getpid()
        print 2,tf.age,tf,'\n'
        while True:
            print u'我是子进程',os.getpid()
            time.sleep(5)
    
    def parent_work():
        print 1,tf.age,tf,'\n'
        while True:
            print u'我是主进程',os.getpid()
            time.sleep(5)
    
    def fork_many_child(count):
    
        if count == 0:
            parent_work()
    
        pid1=os.fork()
        if pid1==0:
            child_work()
        else:
            fork_many_child(count-1)
    
    if __name__ == '__main__':
        fork_many_child(3)

    在父进程中,我创建了一个TestFork对象,子进程里去修改age的值,然后打印,你会发现,每个进程都有自己的tf对象,实际运行结果如下

    1 10 <__main__.TestFork instance at 0x101d51950> 
    
    2 57320 <__main__.TestFork instance at 0x101d51950> 
    
    2 57321 <__main__.TestFork instance at 0x101d51950> 
    
    我是主进程 57318
    我是子进程 57320
    2 57319 <__main__.TestFork instance at 0x101d51950> 

    四、收尸

        如果父进程还存在,而子进程退出了,那么子进程会变成一个僵尸进程,父进程必须为他收尸。如果父进程先结束了,而子进程还没有结束,此时,子进程的父进程就变成了init进程,由它来负责为子进程退出后收尸。

        收尸有两种方法,一个是wait,一个是os.waitpid,wait是阻塞的,而os.waitpid可以设置为非阻塞的,本篇重点讲解waitpid。

        waitpid函数定义为  def waitpid(pid, options),第一个参数取值有以下几种情况:

        (1) pid > 0  等待进程ID为pid的子进程,此时是精确打击

        (2) pid = 0 等待与调用进程同一个进程组的任意子进程

        (3) pid = -1 等待任意子进程,此时和wait等价

          (4)   pid < -1 等待进程组ID与pid 绝对值相等的所有子进程

         options 是以下几个标志位的组合

         (1)    os.WNOHANG         如果子进程没有发生变化,则立刻返回,不会阻塞

      (2) os.WUNTRACED    除了关心终止进程的信息,也关心因信号而停止的子进程信息
      (3) os.WCONTINUED   除了关心终止进程的信息,也关心因受到信号而恢复执行的子进程信息
    
     
      函数的返回值有两个,分别为pid 和 status:
      (1) pid = 0  表示子进程没有发生变化,status不需要理会
      (2) pid = -1 表示waitpid调用失败,此时要关心status的值,status 为 ECHLD,表示没有发现有子进程需要等待
                    status 为EINTR,表示函数被信号中断
      (3) pid >0   pid是发生变化的子进程的pid,具体子进程何种状态,因为什么退出,需要根据status来判断
                    如果子进程是正常退出,status就是0
                    如果子进程是被信号杀死的,status记录的就是终止的信号
                    如果子进程被停止,或者恢复执行,status记录对应的值,这里要重点说明一下,假设你是用SIGSTOP信号停止了子进程的运行,这个status的值可不是
    		SIGSTOP所对应的常量值,具体是多少,取决于系统,mac下的和linux下的值是不一样的,那怎么根据status的值来判断是停止还是恢复亦或是被信号
                    杀死呢,还好,系统提供了跨平台的判断方法,具体看下面的例子
      
    #coding=utf-8
    import os
    import time
    import errno
    
    def child_work2():
        # 子进程
        print u'我是子进程',os.getpid()
        i = 0
        while True:
            print u'子进程{i}'.format(i=i)
            i += 1
            time.sleep(3)
    
    def test_wait():
        pid = os.fork()
        if pid == 0:
            child_work2()
        else:
            print u'子进程',pid
            while True:
                try:
                    time.sleep(4)
                    p,status = os.waitpid(pid,os.WNOHANG|os.WUNTRACED|os.WCONTINUED)
                except OSError:
                    print u'没有子进程需要等待'
                    break
    
                print p,status
                if p == 0:
                    pass
                    #print u'子进程没有退出'
                elif p < 0:
                    if status == errno.EINTR:
                        print u'被信号中断'
                    elif status == errno.ECHILD:
                        print u'该pid不可等待'
                else:
                    if os.WIFSTOPPED(status):
                        print u'子进程并没有退出,只是停止工作'
                    elif os.WIFCONTINUED(status):
                        print u'子进程恢复了运行'
                    else:
                        print u'子进程结束了'
                        break
    
                time.sleep(5)
    
    if __name__ == '__main__':
        test_wait()


    理论部分到此为止,还是来一个例子更直观
    程序启动后,父进程创建一个子进程,然后开始进行waitpid操作,子进程则每隔3秒做一次输出。此时执行kill -17 + 子进程的PID,子进程会停止打印,同时
    父进程会提示子进程没有退出,只是停止工作,一段时间后,再执行kill -19 +子进程PID,子进程被唤醒,继续打印,而父进程也会提示子进程恢复了运行,强调一点,
    我刚才讲述的是在mac环境下,mac和linux环境下的信号所对应的常量值是不一样的,执行kill -l,可以查看信号与常量值之间的关系,如果你是linux环境下实验,
    发送停止信号时应该是kill -19,发送恢复信号时,应该是kill -18。

    这编辑器真难用,怎么调整都不行,难道原创的就不能有半点复制的东西么,一旦有复制就成这个鸟样。


    展开全文
  • 进程的定义

    2021-03-10 16:30:30
    进程的定义 一个具有独立功能的程序对某个数据集在处理机上的执行过程和分配资源的基本单位 ...进程的静态结构:进程控制块PCB、程序段、数据结构集。 进程的上下文 进程的上下文:它包含了每个进程执行过程的
  • 进程、线程

    2019-07-10 10:03:15
    进程:就是一定功能的程序段在某个数据段上的一次运行活动,每个进程一个PCB进程控制块,进程实体由程序段、数据段和PCB进程控制块组成。 为什么要引入进程? 如果没有进程概念的系统执行IO程序和计算程序,那么...
  • ² 进程和线程:一个进程可以拥有多个线程。线程没有独立的资源,它共享进程的ID,共享进程的资源。线程是UNIX中最小的调度单位。² 前台进程和后台进程:用户在Shell提示符下键入命令,创建进程,此后该进程
  • 程序、进程和线程 程序: 程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念。而进程是程序在处理机上的...进程是由进程控制块、程序段、数据段三部分组成; 进程具有创建其他进程的功能...
  • 进程是由程序、数据和进程控制块(PCB)三部分组成。进程有生命周期,进程也可以创建进程,这些都是程序所没有的。 进程和线程的区别与联系 调度: 在没有线程机制的操作系统中,进程是调度的基本单位。 当有...
  • 进程基础知识

    2017-06-15 19:03:00
    进程是可并发执行的程序在一个数据集合上的运行过程。 进程是指进程实体的运行过程。 进程和程序比较 进程更能真实地描述并发,而程序不能; ...结构性:由程序段、数据段、进程控制块三部分...
  • 进程与原语

    2021-03-13 20:33:24
    进程可以看为一个原语(类比) 原语没有数据,进程有数据,这条原语的指令,pcb(描述信息和控制信息) 进程和原语都是不可再细分的 原语和进程的出现主要是为了解决程序并发执行时资源共享导致的数据不唯一的...
  • 一个程序对应多个进程,可以同时运行多个,一个进程对应一个程序 程序没有生命周期,进程有生命周期 2、进程的过程 3、进程的状态 4、MMU的作用 1、虚拟内存和物理内存的映射 2、修改内存访问级别 3、...
  • 本文针对以下三容易混淆和出错的问题:(1)Unix系统中用fork...首先理解以下概念:进程控制块进程控制块:PCB是操作系统管理控制进程运行所有的信息集合,主要包括进程描述信息、进程控制和管理信息、资源分...
  • 进程概念——Linux系统编程

    千次阅读 2020-06-05 18:10:14
    文章目录进程概念进程和程序进程运行特性进程状态转换进程控制块PCB进程地址空间进程常用命令killps孤儿进程僵尸进程...一个程序可以对应多个进程,一个进程可以执行一个或多个程序 进程具有并发性,而程序没有 程序没
  • 线程与进程

    2010-07-26 20:01:00
    1、相同点: (a)二者都具有ID,一组寄存器,状态,优先级以及所要遵循的调度策略。 (b) 每个进程都有一个进程控制...(a) 线程是进程的一部分, 一个没有线程的进程是可以被看作单线程的,如果一个进程内拥有多个
  • 进程与程序

    2020-05-16 17:37:32
    进程和程序并不是一一对应的,一个程序执行在不同的数据集上就成为不同的进程,可以进程控制块来唯一地标识每个进程。而这一点正是程序无法做到的,由于程序没有和数据产生直接的联系,既使是执行不同的数据的程序...
  • 操作系统-02进程管理

    2021-02-01 17:49:45
    由程序块、进程控制块(PCB)和数据块三部分组成 进程与程序的区别 进程是程序的次执行过程,没有程序就没有进程 程序是静态的 进程是动态的 进程进行资源的分配和调度,程序不行 例题: 进程和程序是...
  • Linux之进程

    2018-08-27 12:08:01
    进程和程序,通俗理解是这样的: 我们写的代码没有运行的时候它就叫做程序,...进程信息是被放在一个叫做进程控制块的数据结构当中,可以理解为进程属性的集合。 在书上或课本上我们称这种数据结构为PCB(process ...
  • 进程一般由程序,数据集合和进程控制块三部分组成。程序用于描述进程要完成的功能,是控制进程执行的指令集;数据集合是程序在执行时所需要的数据和工作区;程序控制块包含进程的描述信息和控制信息是进程存在的唯一...
  • Linux进程间通信

    2020-04-19 20:19:01
    一个进程之间具有独立性,因此无法直接通信所以才需要操作系统提供进程间通信方式,实现进程间的通信。 操作系统针对不同的通信场景提供了多种不同的通信方式:数据传输–管道/消息队列;数据共享–共享内存;进程...
  • 以linux系统为例,每个进程或线程都对应内核中的一个PCB进程控制块,而CPU就是通过调度PCB控制块,来调度线程/进程,所以线程和进程在CPU看来并没有什么 区别 必要知识: 每个进程在内核中都有一个进程控制块(PCB)...
  • 每个进程都有自己独立的一内存空间,一个进程可以启动多个线程。比如在Windows系统中,一个运行的exe就是一个进程。 线程线程是程序中一个单一的顺序控制流程.在单个程序中同时运行多个线程完成不同的工作,称.....
  • 进程四要素

    2012-12-06 00:18:00
    在内核中有个一task_struct数据结构,即通常说的“进程控制块”。有了这数据结构,进程才可以接受内核的调度。 4. 有独立的用户空间 注意:有独立的用户空间的是进程,没有独立用户空间的但有共享用户空间的是...
  • 程序 (静态的代码) 只是一组指令的有序集合...进程和程序并不是一一对应的,一个程序执行在不同的数据集上就成为不同的进程,可以进程控制块来唯一地标识每个进程。而这一点正是程序无法做到的。一般来说,一...
  • 3 进程信息被放在一进程控制块的数据结构中,这个进程控制块称为PCB,进程控制块的数据结构叫task_struct 二。进程和程序的区别: (1)存储位置不同,程序在硬盘上,进程在内存里 (2)进程除了拥有和程序一样的...
  • 程序、进程、线程

    2018-10-03 09:51:56
    程序 程序是指令和数据的有序集合,其本身没有任何运行的含义...进程是由进程控制块、程序段、数据段三部分组成;进程具有创建其他进程的功能,而程序没有。同一程序同时运行于若干数据集合上,它将属于若干不同...
  • 进程是由进程控制块、程序段、数据段三部分组成;进程具有创建其他进程的功能,而程序没有。 同一程序同时运行于若干个数据集合上,它将属于若干个不同的进程。也就是说同一程序可以对应多个进程。 (1)进程的基本概念...
  • 实验中,因为进程没有数据和程序,仅使用进程控制块模拟进程,所以这部分内容仅包括进程状态。 ③ 现场信息 现场信息记录各个寄存器的内容。当进程由于某种原因让出处理器时,需要将现场信息记录在进程控制块中...
  • 进程和线程的区别

    2017-08-10 19:12:50
    1.线程是进程的一部分,一个进程可以拥有多个线程; 2.线程的改变只代表了CPU执行过程的改变,而没有发生进程所拥有的资源的变化。除了CPU以外,系统的资源分配和线程无关,线程只能共享其它所属进程的资源; 3.没个...

空空如也

空空如也

1 2 3 4 5 ... 18
收藏数 349
精华内容 139
关键字:

一个进程可以没有进程控制块