LINUX C系统编程学习笔记-----------进程通信(一)

进程间通信(一)

 1.为什么需要进程间通信?

① 数据转移

一个进程需要它的数据发送给另一个进程

② 资源共享

多进程之间共享同样的资源

③ 通知事件

一个进程需要想另一个或一组进程发送消息,通知他们发生了什么事件

④ 进程控制

一个进程控制另一个进程的执行

一.管道通信 

 

管道定义:

管道是单向的,先进先出的,它把一个进程的输出和另一个进程的输出连接在一起,一个进程(写进程)在管道尾部写入数据,另一个进程(读进程)从管道头部读出数据。

管道分类:

无名管道: 用与父进程和子进程之间的通信

有名管道: 用于运行于同一系统中任意两进程间的通信

 

无名管道:    

 int pipe(int filedis[2]):

创建无名管道,管道建立时,它会创建两个文件描述符,

filedis[0] 用于读管道;filedis[1] 用于写管道

关闭管道只需要将这两个文件描述符关闭即可,用close逐个关闭 

 例: 

#include <stdio.h>
#include <errno.h>     //---------关于errno.h看这 http://www.cnblogs.com/riky/archive/2008/02/02/1062750.html
#include <unistd.h>
#include <stdlib.h>

int main( void)
{
     int pipe_fd[ 2]
     if (pipe(pipe_fd) <  0)
    {
        printf( " pipe creat error!\n ");
         return - 1;
    }
     else
        printf( " pipe creat success!\n ");
    close (pipe_fd[ 0]);
    close (pipe_fd[ 1]);

注意:必须要在系统调用fork之前调用pipe(),否则子进程将不会继承文件描述符

 例:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>

int main( void)
{
     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 creat 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 form 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 write Hello!\n ");
         if (write(pipe_fd[ 1], " Pipe ", 5) != - 1)
            printf( " parent write Pipe!\n ");
        close(pipe_fd[ 1]);
        sleep( 3);
    waitpid(pid,NULL, 0);
    exit( 0);
    }

下面是写


命名管道:

#include <sys/types.h>

#include <sys/stat.h>

int mkfifo(const char * pathname,mode_t mode);

pathname: FIFO文件名 

mode:属性(同文件操作)

创建了FIFO,就可以用OPEN打开它,一般的文件访问函数(close,read,write等)都可用于FIFO 。

 

 当打开FIFO时,非阻塞标志(O_NONBLOCK)将对以后读写产生的影响:

  1· 没有使用O_NONBLOCK:访问要求无法满足时,进程阻塞,如试图读取空的FIFO,将导致进程阻塞。

2·使用O_NONBLOCK: 访问要求无法满足时,不发生阻塞,立刻返回,errno是ENXIO。

例:

这个是读 :

 /*

  *********             *********
  ********* fifo_read.c *********
  *********             *********
*/

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include < string.h>

#define FIFO "/home/scrat/code/myfifo"

int main( int argc, char **argv)
{
     char buf_r[ 100];
     int fd;
     int nread;
    
//   创建管道
    
     if ((mkfifo(FIFO,O_CREAT|O_EXCL) <  0) && (errno != EEXIST))
        printf( " prepraing for reading bytes ~~~~~ ");
//   打开管道
    
    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 form FIFO\n ",buf_r);
    sleep( 1);
    }
    pause();        //    暂停,等待
    unlink(FIFO);   //    删除文件FIFO
}

 

 

下面这个是写: 

/*
  *********              *********
  ********* fifo_write.c *********
  *********              *********
*/
#include <stdio.h>
#include <stdlib.h>
#include < string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>

#define FIFO_SERVER "/home/scrat/code/myfifo"

int main( int argc,  char ** argv)
{
     int fd;
     char w_buf[ 100];
     int nwrite;

//   打开管道

    fd = open(FIFO_SERVER,O_WRONLY|O_NONBLOCK, 0);
     if (argc ==  1)
    {
        printf( " Please send something\n ");
        exit(- 1);
    }
    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);


     return  0;


 

你可能感兴趣的:(linux)