Linux管道默认无法阻塞问题排查记录

11 篇文章 1 订阅

概括

  1. read 返回0时,代表对端关闭管道
  2. 不要使用虚拟机共享目录做以下测试,否则可能会出现:open不阻塞,无法mkfifo,recv在没有数据的情况下一直返回0等问题;
  3. 只要不设置非阻塞,默认打开的就是阻塞,接收方必须等待发送端打开,否则处于阻塞open
  4. 发送端只要不close,那么接收端recv就不会返回数据
  5. 接受方返回数据,一个是有数据,另外一个时对端关闭

测试代码

发送端

#include <iostream>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

using namespace std;

#define REQ_FIFO "fifo"

void *UsrReq()
{
    int fd = -1, ret;
    string temp = "hello";

    if (access(REQ_FIFO , F_OK) == -1)
    {
        if ((mkfifo(REQ_FIFO , 0664) < 0) && (errno != EEXIST))
        {
            printf("[]mkfifo failed! %s(%d)\n", __FUNCTION__, __LINE__);
            return NULL;
        }
    }

    fd = open(REQ_FIFO , O_WRONLY);
    if (fd == -1)
    {
        printf("[]open fifo failed! %s(%d)\n", __FUNCTION__, __LINE__);
        return NULL;
    }

    // while (true)
    {
        /* code */
        ret = write(fd, (void *)temp.c_str(), temp.length());
        cout << "write : " << temp << "ret: " << ret << endl;
        sleep(2);
    }

    getchar();

    //(void)close(fd);
    return NULL;
}

int main(int argc, char *arg[])
{
    UsrReq();

    while (true)
    {
        sleep(1);
    }

    return 1;
}

接收端

#include <iostream>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

using namespace std;

#define  FIFO   "fifo"


void *SrvResp()
{
	int  fd = -1;
	int  ret;
	char temp[8] = {0};

	if(access(FIFO   , F_OK) == -1)
	{
		if((mkfifo(FIFO   , 0664) < 0) && (errno != EEXIST))
		{
			printf("[]creat fifo failed! %s(%d)\n", __FUNCTION__, __LINE__);
			return NULL;
		}
	}

	fd = open(FIFO   , O_RDONLY);
	if(fd == -1)
	{
		printf("[]open fifo failed! %s(%d)\n", __FUNCTION__, __LINE__);
		return NULL;
	}
	while(1)
	{
		ret = read(fd, &temp, sizeof(temp));
		if(ret >= 0)
		{
			cout<<"Ret:"<<ret <<"Recv: "<< temp <<endl;
			sleep(1);
		}
		else
		{
			printf("read fifo failed! %s(%d), ret:%d %d %s\n", __FUNCTION__, __LINE__, ret, errno, strerror(errno));
			break;
		}
		(void)usleep(3000);
	}
	
	(void)close(fd);

	return NULL;
}

int main(int argc, char* arg[])
{
	SrvResp();

    return 1;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值