Linux下read函数默认到底是阻塞的还是非阻塞的?

shmilyxbq 2009-07-06 03:51:33
Unix网络编程那边书上说,read默认就是阻塞的,但我怎么在Linux2.6.25 fc9下感觉read()默认就是非阻塞的捏?
1. Linux下read函数默认到底是阻塞的还是非阻塞的?
2. 怎样让read在无数据可读的时候阻塞调用进程/线程捏?
谢谢大家!
...全文
18172 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
ashy1q 2012-01-06
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 badboydw 的回复:]

引用 14 楼 billow_zhang 的回复:
read函数只是一个通用的读文件设备的接口。是否阻塞需要由设备的属性和设定所决定。一般来说,读字符终端、网络的socket描述字,管道文件等,这些文件的缺省read都是阻塞的方式。如果是读磁盘上的文件,一般不会是阻塞方式的。但使用锁和fcntl设置取消文件O_NOBLOCK状态,也会产生阻塞的read效果。


经典
[/Quote]

确实经典,正在学习这块儿,今天把老帖子都翻出来了,看看,呵呵
badboydw 2011-07-16
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 billow_zhang 的回复:]
read函数只是一个通用的读文件设备的接口。是否阻塞需要由设备的属性和设定所决定。一般来说,读字符终端、网络的socket描述字,管道文件等,这些文件的缺省read都是阻塞的方式。如果是读磁盘上的文件,一般不会是阻塞方式的。但使用锁和fcntl设置取消文件O_NOBLOCK状态,也会产生阻塞的read效果。
[/Quote]

经典
银河里游方舟 2009-08-27
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 billow_zhang 的回复:]
read函数只是一个通用的读文件设备的接口。是否阻塞需要由设备的属性和设定所决定。一般来说,读字符终端、网络的socket描述字,管道文件等,这些文件的缺省read都是阻塞的方式。如果是读磁盘上的文件,一般不会是阻塞方式的。但使用锁和fcntl设置取消文件O_NOBLOCK状态,也会产生阻塞的read效果。
[/Quote]
详细~
Wolf0403 2009-07-07
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 shmilyxbq 的回复:]
都没有回答我的问题啊~我的问题很简单:
1. Linux下read函数默认到底是阻塞的还是非阻塞的?
2. 怎样让read在无数据可读的时候阻塞调用进程/线程捏?
[/Quote]

你在读什么东西时候判断是否阻塞?如果是块设备或者块设备上的文件,这些被定义为快速设备的对象,是无论如何都不会阻塞的;某些 char 设备、pipe, fifo, socket 等“慢速设备”在读写时候会阻塞。
shmilyxbq 2009-07-07
  • 打赏
  • 举报
回复
问题解决,结贴了!
由于本人的粗心大意,将源代码移动后忘记改变管道路径的宏定义:
#define FIFOPATH1 "/home/xbq/dev/thread/fifo1"
#define FIFOPATH2 "/home/xbq/dev/thread/fifo2"
由于我对Unix IO函数边界值不熟悉,所以程序中没有错误捕捉的代码,这也导致我没能及时发现这个低级错误!
踏踏实实,一步一个脚印地学习Unix编程!引以为戒
Wolf0403 2009-07-07
  • 打赏
  • 举报
回复
写一个线程一读,线程二写的简单例子试试。
shmilyxbq 2009-07-07
  • 打赏
  • 举报
回复
源代码,不加错误信息捕捉。线程thread1();向线程thread2();发送一个字符串,线程thread2();收到后修改返回给thread1();,thread1();打印收到字符串。

#include <iostream>
#include <string.h> //strlen()
#include <fcntl.h> //O_WRONLY O_RDONLY
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h> //mkfifo()
#include <errno.h> //EEXIST

#define FIFOPATH1 "/home/xbq/dev/thread/fifo1"
#define FIFOPATH2 "/home/xbq/dev/thread/fifo2"
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)

using namespace std;

void* thread1 (void*)
{
int readfd, writefd;
char* buff = (char*)"nihao thread!";

writefd = open(FIFOPATH1, O_WRONLY, 0);
readfd = open(FIFOPATH2, O_RDONLY, 0);
int len = strlen(buff);

write(writefd, buff, len);
read(readfd, buff, 512);
cout << buff << "in thread1" << endl;
close(readfd);
close(writefd);
}

void* thread2 (void*)
{
int readfd, writefd, n;
char* buff;
buff = new char[15];

readfd = open(FIFOPATH1, O_RDONLY, 0);
writefd = open(FIFOPATH2, O_WRONLY, 0);

cout << read(readfd, buff, 13) << endl;
buff[strlen(buff)] = '\0';
cout << buff << "in thread2" << endl;
sprintf(buff, "%s%s", buff, "!!");
cout << buff << "in thread2" << endl;
write(writefd, buff, strlen(buff));

delete buff;
close(readfd);
close(writefd);
}

int main (void)
{
pthread_t tid1, tid2;
cout << pthread_self() << endl;
cout << mkfifo(FIFOPATH1, FILE_MODE);
cout << mkfifo(FIFOPATH2, FILE_MODE);

pthread_create(&tid1, NULL, thread1, NULL);
pthread_create(&tid2, NULL, thread2, NULL);

unlink(FIFOPATH1);
unlink(FIFOPATH2);
return 0;
}
shmilyxbq 2009-07-07
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 Wolf0403 的回复:]
引用 4 楼 shmilyxbq 的回复:

都没有回答我的问题啊~我的问题很简单:
1. Linux下read函数默认到底是阻塞的还是非阻塞的?
2. 怎样让read在无数据可读的时候阻塞调用进程/线程捏?


你在读什么东西时候判断是否阻塞?如果是块设备或者块设备上的文件,这些被定义为快速设备的对象,是无论如何都不会阻塞的;某些 char 设备、pipe, fifo, socket 等“慢速设备”在读写时候会阻塞。
[/Quote]
我是在读一个FIFO的时候,想在open("/path/fifoname", O_RDONLY, 0);这一步把这个有名管道设置成阻塞的,
任何地方都说默认是阻塞的,但是我测试感觉是非阻塞的,数据没过来read()就返回了,总之没读到数据。
请问显式的改怎么做?如果显式的设置阻塞后仍然读不到数据,那我就把这个“阻塞”问题排除了,再看是不是其他地方出了问题,谢谢!
billow_zhang 2009-07-07
  • 打赏
  • 举报
回复

read函数只是一个通用的读文件设备的接口。是否阻塞需要由设备的属性和设定所决定。一般来说,读字符终端、网络的socket描述字,管道文件等,这些文件的缺省read都是阻塞的方式。如果是读磁盘上的文件,一般不会是阻塞方式的。但使用锁和fcntl设置取消文件O_NOBLOCK状态,也会产生阻塞的read效果。
shmilyxbq 2009-07-06
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 ido158 的回复:]
楼主很偏执,仔细看楼上的那些回答,不可能得不到答案。

你要的例子 在linux下打 man select 就可以得到例子。
[/Quote]

还是得不到答案,请大家指点!谢谢
犇犇犇程序猿 2009-07-06
  • 打赏
  • 举报
回复
楼主很偏执,仔细看楼上的那些回答,不可能得不到答案。

你要的例子 在linux下打 man select 就可以得到例子。
shmilyxbq 2009-07-06
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 shmilyxbq 的回复:]
引用 8 楼 shmilyxbq 的回复:

在open的时候,如何显式地把设备描述符设置成read阻塞的呢?能不能直接写个例子,谢谢!
在open的时候,如何显式地把打开的文件设置成read阻塞的呢?能不能直接写个例子,谢谢!

[/Quote]
那么在open的时候,如何显式地把打开的设备文件设置成read阻塞的呢?能不能直接写个例子,谢谢!
shmilyxbq 2009-07-06
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 shmilyxbq 的回复:]
在open的时候,如何显式地把设备描述符设置成read阻塞的呢?能不能直接写个例子,谢谢!
[/Quote]
在open的时候,如何显式地把打开的文件设置成read阻塞的呢?能不能直接写个例子,谢谢!
shmilyxbq 2009-07-06
  • 打赏
  • 举报
回复
在open的时候,如何显式地把设备描述符设置成read阻塞的呢?能不能直接写个例子,谢谢!
墙角的青蛙 2009-07-06
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 shmilyxbq 的回复:]
引用 3 楼 hdukg 的回复:
引用楼主 shmilyxbq 的帖子:

Unix网络编程那边书上说,read默认就是阻塞的,但我怎么在Linux2.6.25 fc9下感觉read()默认就是非阻塞的捏?
1. Linux下read函数默认到底是阻塞的还是非阻塞的?
2. 怎样让read在无数据可读的时候阻塞调用进程/线程捏?
谢谢大家!

楼主可以用select函数实现阻塞调用。具体select如何使用网上有很多的例子。



我目前只有一个读入需求,想直接利用read…
[/Quote]
1、个人认为默认的应该是阻塞的。
2、如果你想阻塞读取,可以open的时候设置好参数,同时设置好VMIN和VTIME的值应该可以。
lidi82 2009-07-06
  • 打赏
  • 举报
回复
阻塞的吧
shmilyxbq 2009-07-06
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 hdukg 的回复:]
引用楼主 shmilyxbq 的帖子:

Unix网络编程那边书上说,read默认就是阻塞的,但我怎么在Linux2.6.25 fc9下感觉read()默认就是非阻塞的捏?
1. Linux下read函数默认到底是阻塞的还是非阻塞的?
2. 怎样让read在无数据可读的时候阻塞调用进程/线程捏?
谢谢大家!

楼主可以用select函数实现阻塞调用。具体select如何使用网上有很多的例子。
[/Quote]

我目前只有一个读入需求,想直接利用read的阻塞特性,select太复杂了
shmilyxbq 2009-07-06
  • 打赏
  • 举报
回复
都没有回答我的问题啊~我的问题很简单:
1. Linux下read函数默认到底是阻塞的还是非阻塞的?
2. 怎样让read在无数据可读的时候阻塞调用进程/线程捏?
墙角的青蛙 2009-07-06
  • 打赏
  • 举报
回复
[Quote=引用楼主 shmilyxbq 的帖子:]
Unix网络编程那边书上说,read默认就是阻塞的,但我怎么在Linux2.6.25 fc9下感觉read()默认就是非阻塞的捏?
1. Linux下read函数默认到底是阻塞的还是非阻塞的?
2. 怎样让read在无数据可读的时候阻塞调用进程/线程捏?
谢谢大家!
[/Quote]
楼主可以用select函数实现阻塞调用。具体select如何使用网上有很多的例子。
ShowMan 2009-07-06
  • 打赏
  • 举报
回复
Linux下线程的挂起和恢复

POSIX的Linux操作系统没有提供线程挂起和恢复的例程,在网上找了找,看到一个老外写的程序,感觉想法不错,放在这里大家分享一下。理论上应该可以实现,不过我没有试,给大家提供一个参考。
void CPrcThread<Worker>::suspend()
{
ifdef WIN32
//do windows specific things here...
#endif

#ifdef __linux__
pthread_mutex_lock(&mutex);
flag--;
pthread_mutex_unlock(&mutex);
#endif
}

void CPrcThread<Worker>::resume()
{
#ifdef WIN32
//do windows specific things here...
#endif

#ifdef __linux__
pthread_mutex_lock(&mutex);
flag++;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
#endif
}

void* CPrcThread<Worker>::threadFunc(void* pParameter)
{

while(1)
{

#ifdef WIN32
//do windows specific things here...
//no member variables accessed here so its ok...
#endif


#ifdef __linux__
pthread_mutex_lock(&mutex);
while(flag <= 0)
{
pthread_cond_wait(&cond, &mutex);
}
pthread_mutex_unlock(&mutex);
#endif


//actual thread work here

}

}
加载更多回复(1)

23,124

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧