`

IPC机制和实现

 
阅读更多

(1)管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。

  (2)命名管道(named pipe):命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。命名管道在文件系统中有对应的文件名。命名管道通过命令mkfifo或系统调用mkfifo来创建。

  (3)信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数)。

  (4)消息(Message)队列:消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺

   创建: msgget();写入消息:msgsnd();读取消息:msgrcv();删除:msgctl();

    (5)共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥

   创建:shmget();附加:shmat();分离:shmdt();

    (6)内存映射(mapped memory):内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。

  (7)信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段

   创建:semget();控制删除:semctl();

    (8)套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。

 

一、管道

(1)管道

    管道是单向的、先进先出的、无结构的、固定大小的字节流它把一个进程的标准输出和另一个进程的标准输入连接在一起。写进程在管道的尾端写入数据,读进程在管道的首端读出数据。数据读出后将从管道中移走,其它读进程都不能再读到这些数据。管道提供了简单的流控制机制。进程试图读空管道时,在有数据写入管道前,进程将一直阻塞。同样,管道已经满时,进程再试图写管道,在其它进程从管道中移走数据之前,写进程将一直阻塞。读写管道的例程:

#include
#include
#include
#include
#include

int main()
{
 int pipe_fd[2];
 pid_t pid;
 char buf_r[100];
 char* p_wbuf;
 int r_num;
 memset(buf_r,0,sizeof(buf_r));
 if(pipe(pipe_fd)<0)
 {
 printf("pipe create error\n");
 return -1;
 }
 if((pid=fork())==0)   //在子进程中读管道(关闭写管道)
 {
  printf("\n");
  close(pipe_fd[1]);
  sleep(2);
  if((r_num=read(pipe_fd[0],buf_r,100))>0){
   printf(   "%d numbers read from the pipe is %s\n",r_num,buf_r);
  } 
  close(pipe_fd[0]);
  exit(0);
   }
 else if(pid>0)    //在父进程中写管道(关闭读管道)
 {
  close(pipe_fd[0]);
  if(write(pipe_fd[1],"Hello",5)!=-1)
   printf("parent write1 success!\n");
  if(write(pipe_fd[1]," Pipe",5)!=-1)
   printf("parent write2 success!\n");
  close(pipe_fd[1]);
  sleep(3);
  waitpid(pid,NULL,0);  //等待子进程结束
  exit(0);
 }
}

(2)标准流管道

 #include
#include
#include
#include

#define BUFSIZE 1000

int main()
{
 FILE *fp;
 char *cmd = "ps -ef";
 char buf[BUFSIZE];
 buf[BUFSIZE] = '\0'; 
 if((fp=popen(cmd,"r"))==NULL)
  perror("popen");
 while((fgets(buf,BUFSIZE,fp))!=NULL)
  printf("%s",buf);
 pclose(fp);
 exit(0);
}

(3)命名管道

     也叫FIFO,与管道不同,FIFO不是临时的对象,它们是文件系统中真正的实体,可以用mkfifo命令创建。只要有合适的访问权限,进程就可以使用FIFOFIFO的打开方式和管道稍微不同。一个管道(它的两个file数据结构、VFS I节点和共享数据页)是一次性创建的,而FIFO已经存在,可以由它的用户打开和关闭。Linux必须处理在写进程打开FIFO之前读进程对它的打开,也必须处理在写进程写数据之前读进程对管道的读。除此以外,FIFO几乎和管道的处理完全一样,而且它们使用一样的数据结构和操作。

读进程:

#include
#include
#include
#include
#include
#include
#include
#define FIFO "/tmp/myfifo"

main(int argc,char** argv)
{
 char buf_r[100];
 int  fd;
 int  nread;
 
 if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST))
  printf("cannot create fifoserver\n");
 printf("Preparing for reading bytes...\n");
 
 memset(buf_r,0,sizeof(buf_r));
 fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);
 if(fd==-1)
 {
  perror("open");
  exit(1); 
 }
 while(1)
 {
  memset(buf_r,0,sizeof(buf_r));
  
  if((nread=read(fd,buf_r,100))==-1){
   if(errno==EAGAIN)
    printf("no data yet\n");
  }
  printf("read %s from FIFO\n",buf_r);
  sleep(1);
 } 
 pause();
 unlink(FIFO);
}

写进程:

#include
#include
#include
#include
#include
#include
#include
#define FIFO_SERVER "/tmp/myfifo"

main(int argc,char** argv)
{
 int fd;
 char w_buf[100];
 int nwrite;
 
 if(fd==-1)
  if(errno==ENXIO)
   printf("open error; no reading process\n");
 fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);
 if(argc==1)
  printf("Please send something\n");
 strcpy(w_buf,argv[1]);
 if((nwrite=write(fd,w_buf,100))==-1)
 {
  if(errno==EAGAIN)
   printf("The FIFO has not been read yet.Please try later\n");
 }
 else
  printf("write %s to the FIFO\n",w_buf);
}

二、信号

(1)信号的发出:kill(),raise()给自身进程发送信号。

#include
#include
#include
#include
#include

int main()
{
 pid_t pid;
 int ret;
 if((pid=fork())<0){
  perror("fork");
  exit(1);
 }
 if(pid == 0){
  raise(SIGSTOP);
  exit(0);
 }
 else{
  printf("pid=%d\n",pid);
  if((waitpid(pid,NULL,WNOHANG))==0){
   if((ret=kill(pid,SIGKILL))==0)
    printf("kill %d\n",pid);
   else{
    perror("kill");
   }
  }
 }
}

(2)alarm(),pause()

#include
#include
#include

int main()
{
        int ret;
        ret=alarm(5);
        pause();
        printf("I have been waken up.\n",ret);
}

(3)signal(),发送信号

ctrl+c:SIGINT,ctrl+/:SIGQUIT

#include
#include
#include
void my_func(int sign_no)
{
 if(sign_no==SIGINT)
  printf("I have get SIGINT\n");
 else if(sign_no==SIGQUIT)
  printf("I have get SIGQUIT\n");
}
int main()
{
 printf("Waiting for signal SIGINT or SIGQUIT \n ");
 signal(SIGINT, my_func);
 signal(SIGQUIT, my_func);
 pause();
 exit(0);
}

(4)信号集,接受多个信号,同时多个信号处理函数

#include
#include
#include
#include
#include

void my_func(int signum)
{
 printf("If you want to quit,please try SIGQUIT\n");
}
int main()
{
 sigset_t set,pendset;
 struct sigaction action1,action2;
 if(sigemptyset(&set)<0)
  perror("sigemptyset");
 if(sigaddset(&set,SIGQUIT)<0)
  perror("sigaddset");
 if(sigaddset(&set,SIGINT)<0)
  perror("sigaddset");
 if(sigprocmask(SIG_BLOCK,&set,NULL)<0)
  perror("sigprocmask");
 else
 {
  printf("blocked\n");
  sleep(5);
 }
 if(sigprocmask(SIG_UNBLOCK,&set,NULL)<0)
  perror("sigprocmask");
 else
  printf("unblock\n");
 while(1){
  if(sigismember(&set,SIGINT)){
   sigemptyset(&action1.sa_mask);
   action1.sa_handler=my_func;
   sigaction(SIGINT,&action1,NULL);
  }else if(sigismember(&set,SIGQUIT)){
   sigemptyset(&action2.sa_mask);
   action2.sa_handler = SIG_DFL;
   sigaction(SIGTERM,&action2,NULL);
  }
 }
}

 

分享到:
评论

相关推荐

    Android IPC机制demo

    本文将深入探讨Android IPC机制,并通过具体的ContentProvider和Socket通信实例进行详细解析。 首先,理解Android IPC的重要性是至关重要的。由于Android系统采用严格的权限隔离,每个应用运行在自己的进程中,这...

    Android的IPC机制-Binder

    4. **统一性**:Binder机制不仅适用于C/C++环境,还适用于Java环境,使得整个Android平台的IPC机制更加统一和一致。 #### Binder机制的关键组成部分 - **Binder Driver**:位于内核空间,负责底层的通信细节处理。...

    Linux系统中IPC机制的分析与实现.pdf

    信号是Linux系统中的一种IPC机制,用于实现进程间的通信和同步。信号可以分为两种:同步信号和异步信号。同步信号是指进程在执行某个操作时,需要等待另一个进程的响应;异步信号是指进程在执行某个操作时,不需要...

    一种安全高效的Java操作系统IPC机制的设计与实现.pdf

    设计和实现了一种新型的安全高效的Java操作系统IPC机制 MSP,以解决当前Java操作系统中的IPC机制存在的安全性和高效性问题。 IPC机制是操作系统中实现进程间协同工作的关键。当前大多数Java操作系统中使用的IPC...

    一个实现IPC机制的例子

    IPC机制在多任务和分布式系统中至关重要,因为它允许进程之间进行有效且安全的信息交换。本篇文章将详细讲解四种常见的IPC机制,并通过一个名为“MessagerTest”的例子来进一步阐述。 1. **管道(Pipes)** 管道是一...

    TUXEDO:基于IPC机制浅析TUXEDO及其应用

    - Tuxedo通过IPC机制实现了进程间的高效通信。 - IPC机制的选择和配置直接影响Tuxedo的性能表现。 #### 在实际工作中的应用和建议 1. **优化IPC配置** - 根据应用的具体需求调整IPC相关的系统参数。 - 例如,...

    深入理解linux内核ipc机制

    这种方式通常与其他IPC机制(如信号量)结合使用,以实现进程间的同步和互斥。 ##### 5. 信号量(Semaphore) - **信号量** 主要用作进程间或同一进程中不同线程之间的同步手段。通过信号量可以实现对共享资源的...

    IPC机制的demo

    综上所述,“IPC机制的demo”是一个全面介绍Android IPC技术的实践案例集,其中的“ipcTest”文件可能包含了上述四种通信方式的具体代码和应用场景,帮助开发者理解和掌握Android中不同进程间通信的各种手段。...

    Linux IPC机制安全性的研究及改进.pdf

    1. 设计和实现更精细的权限控制:为每种IPC机制添加更细粒度的访问控制列表(ACL),使得只有特定的进程或用户才能访问特定的IPC资源。 2. 引入审计机制:跟踪和记录所有IPC操作,以便及时发现异常行为并进行响应。 ...

    linuxIPC机制安全性的研究及改进

    ### Linux IPC机制安全性的研究及改进 #### 一、引言 随着计算机技术的发展与网络应用的日益广泛,操作系统安全成为了一个不容忽视的问题。Linux作为一款广泛应用的操作系统,其进程间通信(Inter-Process ...

    掌握AIDL IPC机制

    ### 掌握AIDL IPC机制 #### 一、AIDL IPC机制概述 AIDL(Android Interface Definition Language)是Android系统中用于实现进程间...掌握了AIDL IPC机制后,开发者可以更加自信地设计和实现复杂的Android应用程序。

    Anroid跨进程的IPC机制

    在Android系统中,跨进程通信(IPC,Inter-Process ...通过深入学习上述知识点,并结合《Android跨进程的IPC机制》一书中的实例和讲解,开发者能够更好地理解和应用Android的IPC机制,提升应用的健壮性和扩展性。

    AndroidIPC通讯机制源码分析[归类].pdf

    在Android系统中,Binder通信机制是其核心的进程间通信(IPC)方式,相较于其他Linux系统中的IPC方式如socket、named pipe、message queue等,Binder以其高效性与独特设计成为Android首选。 Binder通信依赖于Linux...

    c6678实现IPC

    通过分析和学习这些例子,开发者可以更好地理解如何在C6678上实现有效的IPC机制。在实践中,还应注意性能优化,如避免不必要的数据复制,减少中断延迟,以及充分利用硬件提供的并行特性。 总的来说,C6678的IPC实现...

    GB28181在IPC功能实现接入总结

    总之,实现GB28181在IPC上的功能,开发者需要深入了解SIP、RTSP等协议,以及设备注册、事件处理、心跳机制等流程,同时考虑网络和安全因素,确保设备能顺利接入GB28181系统,并与其他设备有效协同工作。通过文档《GB...

    进程间通信 IPC

    "进程间通信 IPC" 进程间通信(Inter-Process Communication,...IPC机制是操作系统中的一种基本机制,用于实现进程之间的协作和通信。不同的IPC机制有其特点和优点,选择合适的IPC机制取决于具体的应用场景和需求。

    IPC面面观.docx

    "IPC面面观" OS 历史的发展中,对于进程之间的通信方式,经历了一个不断完善的过程,其中有三大经典论文的发表,奠定了IPC的...不同的操作系统都有其自己的IPC机制,了解IPC机制对于操作系统的设计和实现非常重要。

    AndroidIPC和binder框架

    Binder作为Android系统中的核心IPC机制,其工作原理和实现机制是本书的重点。Binder不仅是一种接口,更是一个轻量级的进程间通信机制。它允许服务在不同的进程中运行,并通过代理和远程对象的概念实现跨进程调用。...

Global site tag (gtag.js) - Google Analytics