【UNIX】什么是进程间FIFO通信以及信号通信

上篇中的无名管道通信是父子进程之间的通信,限定了进程之间的通信,从而就有了有名管道,它可以使不同进程之间进行通信,有名管道可以通过指定路径名来指出,兵长文件系统中可见。进程通过文件IO来操作有名管道,有名管道遵从先进先出的原则,但是不支持lseek函数。

1)int mkfifo(const char *pthname,mode_t mode)创建有名管道,

2)在内核中创建对象,但没有打开读写,有名管道的读写要自己打开,

3)文件对象在文件系统中创建文件节点,

4)在两个进程中,只会创建一次,若有节点则不会创建,第二次创建会返回错误信息,

FIFO的一般形式函数:

#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
         #include 
        
          #include 
         
           /* open a read endpoint on a FIFO */ int fifo_read (const char *pathname); /* open a write endpoint on a FIFO */ int fifo_write(const char *pathname); /* print usage info */ void usage(const char *argv0); int main(int argc,char *argv[]) { if (argc < 3) { usage(argv[0]); return -1; } if ('r' == argv[1][0]) { if (fifo_read(argv[2]) < 0) { return -1; } } else if ('w' == argv[1][0]) { if (fifo_write(argv[2]) < 0) { return -1; } } else { usage(argv[0]); return -1; } return 0; } int fifo_read (const char *pathname) { int fd; /* * Ignore EEXIST for this case. * EEXIST means the FIFO has been created already. */ if (mkfifo(pathname, 0666) < 0) { if (EEXIST == errno) { printf("FIFO has been created at %s\n", pathname); } else { perror("mkfifo error"); return -1; } } else { printf("FIFO was created at %s\n", pathname); } if ((fd = open(pathname, O_RDONLY)) < 0) { perror("open for read w/ block error"); return -1; } printf("open read endpoint success.\n"); return 0; } int fifo_write(const char *pathname) { int fd; /* * Ignore EEXIST for this case. * EEXIST means the FIFO has been created already. */ if (mkfifo(pathname, 0666) < 0) { if (EEXIST == errno) { printf("FIFO has been created at %s\n", pathname); } else { perror("mkfifo error"); return -1; } } else { printf("FIFO was created at %s\n", pathname); } if ((fd = open(pathname, O_WRONLY)) < 0) { perror("open for write w/ block error"); return -1; } printf("open write endpoint success.\n"); return 0; } void usage(const char *argv0) { printf( "Usage : %s 
           
           
             \n" " 
            
              \n" " r: create read endpoint\n" " w: create write endpoint\n" " 
             
               :\n" " path to the FIFO file in filesystem.\n" , argv0); } 
              
             
            
           
          
         
       
      
      
     
     
    
    
   
   

信号通信

1)信号通信是在软件层次上对中断机制的一种模拟,是一种异步通信方式。

信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了哪些系统事件,

若果该进程当前处于未执行的状态,该信号就由内核保存起来,直到该进程恢复执行再传递给它,若果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到阻塞被取消才传递给进程。

2)信号的生命周期


4)信号在内核中的形式:

1 信号的发生pending 

2 信号在进程中注册

3 信号的投递(执行和注销):执行信号的动作称为信号的投递

//

信号的未决:信号保存在内核中,直到信号被处理,返回给用户态处理

信号的阻塞block

信号的部署:就是处理信号的函数(可以自己制定)信号的处理函数在用户态进行处理,使用信号的阻塞,调用signal函数和pause函数,

内核信号的处理是在特定时间片才执行的(在内核进程退出的前夜统一处理多数信号,返回给用户进程处理过程叫投递)

信号的部署,就是通过系统特定的信号集,比如SIGINT/SIGQUIT/这些系统信号不被CTRL+C处理掉,但可以被KILL杀死


3)用户进程对信号的响应方式:

1 忽略信号:对信号不做任何处理,但是有两个信号不能忽略,就是SIGKILL和SIGSTOP,

2 捕捉信号:定义信号处理函数,当信号发生时,执行响应额处理函数,

3 执行缺省操作:Linux对每种信号都规定了默认操作。

3)信号的使用场合:

后台进程需要使用信号,例如xinetd   

若果两个进程没有亲缘关系,无法使用无名管道

若果两个进程只有只能使用标准输入和标准输出,则不可以使用有名管道。


信号的部署函数的一般形式:


#include
   
   
    
    
#include
    
    
     
     
#include
     
     
      
      
#include
      
      
       
       
#include
       
       
         #include 
        
          pid_t pid; void func1(int sign) { pid_t ppid = getppid(); if (sign == SIGINT) kill(ppid,SIGUSR1); if (sign == SIGQUIT) kill(ppid,SIGUSR2); if(sign == SIGUSR1){ printf("please get off the bus \n"); kill(ppid,SIGKILL); } exit(0); } void func2(int sign) { if (sign == SIGUSR1) printf("let is gogogo\n"); if (sign == SIGUSR2) printf("stop the bus \n"); if (sign == SIGTSTP) kill(pid,SIGUSR1); } int main () { printf("waiting for singal SIGINT or SIGQUIT\n"); pid = fork(); if (pid == -1){ perror("fork"); exit (-1); } if (pid > 0){ signal(SIGTSTP,func2); signal(SIGINT,SIG_IGN); signal(SIGQUIT,SIG_IGN); signal(SIGUSR1,func2); signal(SIGUSR2,func2); pause(); } if (pid == 0){ signal(SIGINT,func1); signal(SIGQUIT,func1); signal(SIGTSTP,SIG_IGN); signal(SIGUSR1,func1); signal(SIGUSR2,SIG_IGN); pause(); } } 
         
       
      
      
     
     
    
    
   
   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值