0
点赞
收藏
分享

微信扫一扫

网页端HTML使用MQTTJs订阅RabbitMQ数据

目录

回顾

进程运行

进程的创建

 进程的工作

举例

进程的删除

举例1(走到return 0结束)

举例2(利用exit(1)结束)

进程通信 

共享内存

生产者算法

消费者算法

消息传递 

定义

 算法实现

总结


回顾

上文的重点就两个内容:一、进程调度的理解;二、队列图以及调度程序

其中进程调度的理解有:一、进程本身角度调度理解;二、计算机整体角度理解进程管理和调度

队列图共有五个队列:I/O队列、中断队列、就绪队列、时间片过期队列、创建子进程队列

调度程序:长期调度程序、短期调度程序

进程运行

研究完进程调度,现在我们来研究进程的运行,研究进程运行前要先看进程是如何创建、删除的

一个进程的一生包括:创建、工作、被调度、删除

进程的创建

所有进程(除了Pid=0的初始进程)都是由父进程创建产生

进程创建必备的两个指令:fork()、exec()

 进程的工作

进程是并行工作的,即子进程被父进程创建后和父进程一起工作(父进程利用wait(NULL)除外,该方法让父进程在子进程结束后才工作)

举例

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

// 测试创建子进程函数 pid_t fork();
int main()
{
    pid_t pid = fork();
    if(-1 == pid)
    {
        //创建子进程失败
        return -1;
    }
    if(0 == pid)
    {
        //子进程
        printf("I am child, my fork:%d\n", pid);
        printf("I am child, my pid:%d, ppid:%d\n",getpid(),getppid());
        sleep(5);
        printf("I am child, I have finished\n");  
    }
    else
    {
        //父进程 
        printf("I am father, my fork:%d\n", pid);      
        printf("I am father, my pid:%d, ppid:%d\n",getpid(),getppid());
        sleep(5);
        printf("I am father, I have finished\n");   
    }
    return 0;
}

执行结果为:

程序运行的关键点: 

进程的删除

进程的删除主要有两种:

1、进程走到return 0 自己结束 

2、进程调用exit(1)结束

举例1(走到return 0结束)

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

// 测试创建子进程函数 pid_t fork();
int main()
{
    pid_t pid = fork();
    if(-1 == pid)
    {
        //创建子进程失败
        return -1;
    }
    if(0 == pid)
    {
        //子进程
        printf("I am child, my fork:%d\n", pid);
        printf("I am child, my pid:%d, ppid:%d\n",getpid(),getppid());
        sleep(5);
        printf("I am child, I have finished\n");  
    }
    else
    {
        //父进程 
        wait(NULL) 
        printf("I am father, my fork:%d\n", pid);      
        printf("I am father, my pid:%d, ppid:%d\n",getpid(),getppid());
        sleep(5);
        printf("I am father, I have finished\n");   
    }
    printf("%d 号进程已结束\n",pid);
    return 0;
}

 结果为:

举例2(利用exit(1)结束)

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

// 测试创建子进程函数 pid_t fork();
int main()
{
    pid_t pid = fork();
    if(-1 == pid)
    {
        //创建子进程失败
        return -1;
    }
    if(0 == pid)
    {
        //子进程
        printf("I am child, my fork:%d\n", pid);
        printf("I am child, my pid:%d, ppid:%d\n",getpid(),getppid());
        sleep(5);
        printf("I am child, I have finished\n");
        exit(1);  
    }
    else
    {
        //父进程 
        wait(NULL) 
        printf("I am father, my fork:%d\n", pid);      
        printf("I am father, my pid:%d, ppid:%d\n",getpid(),getppid());
        sleep(5);
        printf("I am father, I have finished\n");   
    }
    printf("%d 号进程已结束\n",pid);
    return 0;
}

执行结果为:

进程通信 

操作系统内并发执行的进程可以是独立的也可以是协作的,协作完成的进程就涉及到进程间通信

进程通信主要有两种方式:1、共享内存  2、消息传递

共享内存

共享内存实现通信一定要面临一种情况:其中一个进程是消息的发送者,另一个进程是消息的接收者。

这样我们必须要设计算法保证:消息接受者知道消息发送者何时发送

生产者算法
while(true){
    while(((in+1)%BUFFER_SIZE)==out)
        ; //共享内存满了,就不能生产等待消费者进程拿
    buffer[in]=next_produced;
    in=(in+1))%BUFFER_SIZE
}
消费者算法
item next_consumed;
while(true){
    while(in==out)
        ;//此时共享内存是空的,无法拿东西
    next_comsumed=buffer[out];
    out=(out+1)%BUFFER_SIZE;

消息传递 

定义

首先要知道一个消息是由消息头和消息体组成的,消息头里包括:发送进程ID、接收进程ID、消息类型、消息长度等格式化的信息(计算机网络中发送的“报文”其实就是一种格式化的消息)。

直接通信方式,如下:

发送进程把它想要发送的消息,通过发送原语发送给接收进程,然后这些消息会被放到接收进程的消息队列里面,接着接收进程通过接收原语一个个读取消息队列中的消息,这样发送进程和接收进程就实现了线程通信。

间接通信方式,如下:

对于间接通信方式,进程1会先通过发送原语把消息放到一个信箱中,然后进程2会通过接收原语从信箱中读取这些消息。

 算法实现

总结

本文到这里就结束啦~~这堂课的内容较为杂乱、复杂,但是学一学拓展一下知识是非常好的呀~~
如果觉得对你有帮助,辛苦友友点个赞哦~

举报

相关推荐

0 条评论