当前位置:  技术问答>linux和unix

如何用命名管道(FIFO)实现非阻塞模式进程间通讯(IPC)?

    来源: 互联网  发布时间:2016-09-17

    本文导语:  下面代码用阻塞模式实现进程间通讯,Lucy和Kate用阻塞模式进行聊天通讯。 /*Lucy.c*/ #include  #include  #include  #include  #include  #include  /*全局变量*/ char write_fifo_name[] = "read-fifo.txt"; char read_fifo_name[] = "write-fifo.txt"; ...

下面代码用阻塞模式实现进程间通讯,Lucy和Kate用阻塞模式进行聊天通讯。

/*Lucy.c*/
#include 
#include 
#include 
#include 
#include 
#include 

/*全局变量*/
char write_fifo_name[] = "read-fifo.txt";
char read_fifo_name[] = "write-fifo.txt";
int write_fd, read_fd;

/*初始化*/
int kateInitNamedPipe()
{
/*创建管道文件*/ 
int ret = mkfifo(write_fifo_name, S_IRUSR | S_IWUSR);
if ( (ret == -1) &&(errno!=EEXIST)) {
printf("Fail to create FIFO %s: %s", write_fifo_name, strerror(errno));
return -1;
}

/*读管道文件的ID*/   
while ((read_fd = open(read_fifo_name, O_RDONLY)) == -1) 
//while ((read_fd = open(read_fifo_name, O_NONBLOCK)) == -1) 
{
sleep(1);
}

/*读管道文件的ID*/  
write_fd = open(write_fifo_name, O_WRONLY);
//write_fd = open(write_fifo_name, O_NONBLOCK); 
if (write_fd == -1) {
        printf("Fail to open FIFO %s: %s", write_fifo_name, strerror(errno));
        return -1;
}
    return 1;
}

/*写管道文件*/
int kateWriteNamedPipe(int w_fd, char *mscIDState)
{
int wLen = write(w_fd, mscIDState, strlen(mscIDState)); 
return wLen;
}

/*读管道文件*/
int kateReadNamedPipe(int r_fd,char *pCalledNo)
{
int len = read(r_fd, pCalledNo, 256); 
return len;
}

int main(void)

kateInitNamedPipe(); 
char buf[256]; /*每次读写的数据大小*/
int len;       /*读到的数据大小*/
char pMsgToLucy[] ="Hi,Lucy !";

while (1) {  
printf("kate ready to read namedPipen");    
memset(buf,0,sizeof(buf));                   
len = kateReadNamedPipe(read_fd,buf);  

                /*业务处理*/
if ( len > 0) {
buf[len] = '';
printf("Data From Lucy: %s **** Length:%dn", buf,strlen(buf));
  }
else if (len == 0)  /*管道为空*/
{   
printf("Data From Lucy:NULL **** Length:0n");
}
else if (len == -1) /*读管道出现异常*/
{   
printf("Data From Lucy: Error **** Length:-1n");
}       
        printf("kate read namedPipe overn"); 
                  
printf("kate ready to write namedPipen"); 
printf("     Data To Lucy:%s **** Length:%dn",pMsgToLucy,strlen(pMsgToLucy));          
strcpy(buf,pMsgToLucy);                     
kateWriteNamedPipe(write_fd, buf);    
printf("kate write namedPipe overn");
}

close(write_fd);
unlink(write_fifo_name); 
close(read_fd); 
}

/*Kate.c*/
#include 
#include 
#include 
#include 
#include 
#include 
#include 

/*全局变量*/
char write_fifo_name[] = "write-fifo.txt";
char read_fifo_name[] = "read-fifo.txt";
int write_fd, read_fd;  /*管道文件的句柄*/
struct stat stat_buf;   /*结构体对象,暂时未用到*/ 

/*初始化*/
int lucyInitNamedPipe()
{
/*创建命名管道*/   
int ret = mkfifo(write_fifo_name, S_IRUSR | S_IWUSR);
if ( (ret == -1) &&(errno!=EEXIST)) {
printf("Fail to create FIFO!!! %s: %s", write_fifo_name, strerror(errno));
return -1;
}

/*写管道的ID*/  
write_fd = open(write_fifo_name, O_WRONLY);     /*阻塞模式*/
//write_fd = open(write_fifo_name, O_NONBLOCK); /*非阻塞模式*/
if (write_fd == -1) {
printf("Fail to open FIFO %s: %s", write_fifo_name, strerror(errno));
return 0;
}

/*读管道的ID*/
while ((read_fd = open(read_fifo_name, O_RDONLY)) == -1)     /*阻塞模式*/
//while ((read_fd = open(read_fifo_name, O_NONBLOCK)) == -1) /*非阻塞模式*/
{
sleep(1); /*sleep休眠1秒钟*/
}
return 1;
}

/*写管道文件*/
int lucyWriteNamedPipe(int w_fd, char *pCalledNo)
{
int wLen = write(w_fd, pCalledNo, strlen(pCalledNo)); 
return wLen;
}

/*读管道文件*/
int lucyReadNamedPipe(int r_fd,char *mscIDState)
{
int len = read(r_fd, mscIDState, 256); 
return len;
}

int main(void)
{    
lucyInitNamedPipe();             /*管道文件初始化*/
char buf[256];                   /*每次读写的数据大小*/         
int len;                         /*读取的数据长度*/
char pSendMessage[] ="Hi,Kate";   

/*循环读写管道文件*/
while (1) {     
printf("lucy Ready to write namedPipen");         
printf("    Data To Kate :%s Length:%dn",pSendMessage,strlen(pSendMessage));
memset(buf,0,sizeof(buf));  
strcpy(buf,pSendMessage);             /*准备写入管道的数据*/                         
lucyWriteNamedPipe(write_fd, buf);    /*向管道中写数据*/
printf("lucy write namedPipe overn");  
                
printf("lucy Ready to read namedPipen"); 
memset(buf,0,sizeof(buf));                                  
len = lucyReadNamedPipe(read_fd,buf); /*从管道中读文件*/                   

/*业务处理*/
if (len > 0) 
{
buf[len] = '';
printf("Data From Kate : %s **** Length:%dn", buf,len);
}
else if (0 == len) /*管道为空,没有数据可读*/ 
{   
printf("Data From Kate:NULL **** Length:0n"); 
}
else if (len == -1) /*读管道出现异常*/
{   
printf("Data From Kate: Error **** Length:-1n"); 
}
printf("lucy read namedPipe overn");
}

close(write_fd);
unlink(write_fifo_name); 
close(read_fd);  
}

|
write_fd = open(write_fifo_name, O_NONBLOCK); /*非阻塞模式*/
改成
write_fd = open(write_fifo_name, O_WRONLY|O_NONBLOCK); /*非阻塞模式*/
试试

|
直接用O_NONBLOCK有什么问题吗?

|
多读几次试试看

    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 进程间通信:pthread_cond使用在线程间,我要进程间条件同步(没有情缘关系的进程),采用什么方呢?也就是说我要在UNIX实现WIN32上命名Event的功能
  • java命名空间javax.naming类namingexception的类成员方法: getrootcause定义及介绍
  • java文件重命名(文件批量重命名)实例程序代码分享
  • java命名空间javax.xml.soap接口name成员方法: getqualifiedname定义参考
  • 大家讨论一下Linux的命名规则
  • java命名空间javax.naming.event类namingevent的类成员方法: object_renamed定义及介绍
  • 批量重命名工具 Krename
  • java命名空间javax.naming接口context的类成员方法: getnameparser定义及介绍
  • solaris 安装 命名服务
  • java命名空间javax.naming.directory类searchcontrols的类成员方法: subtree_scope定义及介绍
  • 搞不懂TI的demo的线程命名,请教
  • java命名空间javax.swing类jtextpane的类成员方法: addstyle定义及介绍
  • c# 命名空间和程序集
  • java命名空间javax.naming接口namingenumeration<t>的类成员方法: hasmore定义及介绍
  • 如何批量重命名
  • java命名空间javax.swing.text接口styleddocument的类成员方法: addstyle定义及介绍
  • 文件重命名的两种方式的区别
  • java命名空间javax.swing.text类stylecontext的类成员方法: addstyle定义及介绍
  • UINX C++ 命名空间问题
  • java命名空间javax.swing.text类styleconstants的类成员方法: nameattribute定义及介绍
  • java 命名空间 命名规则第1/2页
  • java命名空间javax.xml.soap接口name成员方法: geturi定义参考
  • tar解压重命名


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3