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;


 

posted @ 2012-06-26 10:52  xss  阅读(550)  评论(0编辑  收藏  举报