zoukankan      html  css  js  c++  java
  • 进程和进程间通信

    程序:存放在磁盘文件下的可执行文件

    进程:是一个具有独立功能的程序对某个数据集合的一次运行活动。进程是程序的一个具体实现,进程是执行程序的过程。

               实体结构:进程控制块(PCB),程序段,数据段

    进程控制块:PCB是进程存在的唯一标识,是task_struct的结构体,task_struct==》结构体==》进程表项(进程控制块)

                         进程ID:每个进程只有一个ID,非负整数。

                         状态:有就绪,运行,挂起,停止。      

    并发:在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。

               如浏览器,听歌,qq等同时进行,该过程需要硬件手段时钟中断。

    环境变量:一般是指在操作系统中用来指定操作系统运行环境的一些参数,以字符串“环境变量名=环境变量值”的形式存放的,用来描述进程环境信息

                      echo $PATH  查看环境变量    结果:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games   搜素路径由前到后

                      常用函数 #include<stdlib.h>   getenv  putenv  setenv  应用时上网查看

    fork函数:产生一个子进程

                 子进程的代码是父进程代码一个完全相同的拷贝

                  返回值有2个: 1、父进程返回子进程的pid (非负整数>0) 2、返回0 (子进程)         

    孤儿进程:父进程先于子进程结束,则子进程成为孤儿进程,子进程的父进程成为init进程,称为init进程领养孤儿进程。

    僵尸进程:: 进程终止,父进程尚未回收,子进程残留资源(PCB)存放在内核中,变成僵尸(Zombie)进程

                     僵尸进程是不能使用kill命令清除掉的。 因为kill命令只是用来终止进程的,而僵尸进程已经终止 

    父子进程同步的功臣-------wait函数

    进程间通信   (IPC,InterProcess Communication)

    一、管道(使用最简单,进程间的大动脉)

    1. 进程通信必须经过内核
    2. 管道:管道是一个特殊的文件,是由队列实现的,是单向的,先进先出的,无结构的字节流。
    3. 管道实为内核使用环形队列机制,借助内核缓冲区(4K)实现。
    4. 无名管道(pipe):文件系统中无文件名(节点),不能用open文件创造,只能用pipe函数来创建管道
    5. 无名管道缺点:不能实现不是父子进程(血缘关系)之间的通信
    6. 有名管道(FIFO ) :文件系统中有文件名(节点)
    7.  pipe函数              
      1 //函数形式: init pipe(int fd[2])
      2 //功能:创建管道,为系统调用
      3 //头文件:unistd.h
      4 //参数:得到的文件描述符。 fd[0]:读   出队  fd[1]:写   入队
      5 //返回值:成功0,出错是-1
       1  #include"stdio.h"
       2  #include"unistd.h"
       3  #include"stdlib.h"
       4   int main()
       5   {
       6        int fd[2];
       7        int ret;
       8        ret=pipe(fd);
       9        if(ret<0)
      10        {
      11            printf("creat pipe failure
      ");
      12            return -1;
      13        }
      14         printf("creat pipe sucess fd[0]=%d,fd[1]=%d
      ",fd[0].fd[1]); n
      15         return 0;
      16   }
      17

      输出:creat pipe sucess fd[0]=3,fd[1]=4

       注意:

    • 管道是创建在内存中的,进程结束,空间释放,管道就不存在了
    • 管道的东西读完了就删除
    • 如果管道中没有东西读,则会阻塞

         8、进程间通信

     1 /* simplepipe.c
     2  * parent read chars from stdin, then send them to child through pipe,
     3  * child receive chars from pipe ,then display on stdout
     4 */
     5 #include <stdio.h>
     6 #include <stdlib.h>
     7 #include <unistd.h>
     8 #define BUFSIZE 1024
     9 int main(void) {
    10         int pid, fd[2], n;
    11         char buf[BUFSIZE];
    12         if (pipe(fd) < 0)      //pipe创建管道
    13                 { printf("pipe error
    "); exit(1); }
    14         if ((pid = fork()) < 0)    //创建子进程
    15                 { printf("fork failure
    "); exit(1); }
    16         else if (pid == 0) {  //child
    17                 close(fd[1]);
    18                 while((n = read(fd[0], buf, BUFSIZE))>0) {
    19                         write(STDOUT_FILENO, "receive from parent:  ", 21);
    20                         write(STDOUT_FILENO, buf, n);
    21                 }
    22                 if (n < 0)
    23                         { printf("read error
    "); exit(1); }
    24                 close(fd[0]);
    25                 printf("exit child
    ");
    26                 exit(0);
    27         }
    28         close(fd[0]);
    29         while((n=read(STDIN_FILENO, buf, BUFSIZE)) >0)
    30           write(fd[1], buf, n);
    31         if (n < 0)
    32                 { printf("read error
    "); exit(1); }
    33         close(fd[1]);
    34         printf("exit parent
    ");
    35         return 0;
    36 }
    37 //退出程序:crtl+c

      7.   有名管道:

     通过有名管道,不相关的进程也能交换数据,所谓有名,即文件系统中存在这个一样的文件节点,每一个文件节点都有一个inode号而且这是一个特殊的文件类型:P管道类型

    函数形式: int mkfifo(const char *pathname,mode_t mode)
    功能:创建命名管道,没有在内核中创建管道,只有通过open函数打开打开这个文件时才会在内核空间创建管道
    参数:路径  权限(与umask有关)
    头文件:#include<sys/types.h>
           #include<sys/types.h>      
    返回:若成功为0,若出错则为-1

     管道文件只有inode号,不占磁盘快空间,和套接字、字符设备文件、块设备文件一样。普通文件和符号链接文件及目录文件,不仅有inode号,还占磁盘块空间。

    两个进程通信:

     1 #include "stdio.h"
     2 #include "unistd.h"
     3 #include "stdlib.h"
     4 #include "sys/types.h"
     5 #include "sys/stat.h"
     6 int main()
     7 {
     8    int ret;
     9    ret=mkfifo("./myfifo",0777);
    10    if(ret<0)
    11    {   
    12      printf("creat myfifo failure
    ");
    13      return -1; 
    14    }   
    15    printf("creat myfifo sucess
    ");
    16    return 0;
    17 }
    创建管道
     1 //往管道写 
     2 #include "unistd.h"
     3 #include "stdio.h"
     4 #include "sys/types.h"
     5 #include "stdlib.h"
     6 #include "fcntl.h"
     7 int main()
     8 {
     9    int fd;
    10    int i;
    11    char  process_inter=0;
    12    fd=open("./myfifo",O_WRONLY);//管道被创建
    13    if(fd<0)
    14    {
    15       printf("open myfifo failure
    ");
    16       return -1;
    17    }
    18    printf("open myfifo sucess
    ");
    19    for(i=0;i<5;i++)
    20    {
    21       printf("this is first process i =%d
    ",i);
    22       usleep(100);
    23    }
    24    process_inter=1;
    25    sleep(8);
    26    write(fd,&process_inter,1);//往管道中写
    27    while(1);
    28    return 0;
    29 }
    first.c
     1 //接收first从管道发的数据, 执行相关操作
     2 //以上三个程序放在同一文件夹中,用两个中端查看结果
     3 #include "unistd.h"
     4 #include "stdio.h"
     5 #include "sys/types.h"
     6 #include "stdlib.h"
     7 #include "fcntl.h"
     8 int main()
     9 {
    10    int fd; 
    11    int i;
    12    char  process_inter=0;
    13    fd=open("./myfifo",O_RDONLY);
    14    if(fd<0)
    15    {   
    16       printf("open myfifo failure
    ");
    17       return -1; 
    18    }   
    19    printf("open myfifo sucess
    ");
    20    read(fd,&process_inter,1);
    21    while(process_inter==0);
    22    for(i=0;i<5;i++)
    23    {   
    24       printf("this is first process i =%d
    ",i);
    25       usleep(100);
    26    }   
    27    while(1);
    28    return 0;
    29 }
    second.c

     二、信号(进程间的传令兵)

    1. kill l :查看信号  (一共64种信号)
    2. 信号是信息的载体,Linux/UNIX环境下,古老的、经典的通信方式。信号是软件中断。共性:简单。不能携带大量信息,满足某个特设条件下才发送。
    3. 信号的特质:由于信号是通过软件方法实现,其实现手段导致信号有很强的实延性。但对于用户来说,这个时延非常短,不易察觉
    4. 每个进程收到的所有信号都是由内核负责发送的,内核处理。
    5. 信号四要素:编号、名称、事件、默认处理动作
    6. 递达:递达并且到达进程
    7. 未决:产生和递达之间的状态。主要由于阻塞(屏蔽)导致该状态
    8. 信号的处理方式有:执行默认动作、忽略(丢弃),捕捉(用户处理函数)
    9. PCB包含信号相关的信息,主要是指阻塞信号集和未决信号集 

            

  • 相关阅读:
    CF891E Lust
    Comet OJ 2019 夏季欢乐赛题解
    CF1098E Fedya the Potter
    CF1063F String Journey
    P4218 [CTSC2010]珠宝商
    AGC028 E
    51Nod 1584 加权约数和
    51Nod 1769 Clarke and math2
    Educational Codeforces Round 67
    斯特林数学习笔记
  • 原文地址:https://www.cnblogs.com/wy9264/p/10271360.html
Copyright © 2011-2022 走看看