如何解决Cygwin-打开命名的fifo时导致阻塞,导致另一个线程在打开常规文件时阻塞
在Cygwin中阻塞打开命名管道会导致另一个线程在尝试打开任何文件(包括简单文本文件)时挂起。以下代码重现了cygwin 3.1.6(0.340 / 5/3)上的问题,并且在RHEL 7上正常运行(不挂起)。
#include <unistd.h>
#include <limits.h>
#include <stdio.h>
#include <thread>
#include <sys/stat.h>
#include <fcntl.h>
void openFile() {
int fd;
printf("inside new thread\n");
sleep(10); // Ensure main thread reaches call to open()
printf("opening a simple file\n");
if((fd = open("simpleFile",0600)) == -1) { // simpleFile is a simple text file in the filesystem
printf("Failed opening a simple file\n");
}
printf("simple file opened successfully\n");
close(fd);
printf("simple file closed\n");
}
int main(int argc,char *argv[]) {
int fd;
char readBuffer[PIPE_BUF];
printf("creating named pipe\n");
if (mkfifo("namedPipe",0600)) {
printf("creating named pipe Failed\n");
}
printf("creating thread\n");
std::thread pipeCreator = std::thread(openFile);
printf("opening named pipe for read\n");
fd = open("namedPipe",O_RDONLY); // Block will only release when we echo something into namedPipe
printf("reading from named pipe\n");
if (read(fd,readBuffer,PIPE_BUF) == -1) {
printf("error reading from pipe\n");
}
printf("read successfully from named pipe\n");
pipeCreator.join();
return 0;
}
运行此打印:
creating named pipe
creating thread
opening named pipe for read
inside new thread
opening a simple file
然后阻塞,直到namedPipe的另一侧打开。 释放后,它会打印其余的照片:
reading from named pipe
simple file opened successfully
read successfully from named pipe
simple file closed
在RHEL上,这将打印出预期的结果:
creating named pipe
creating thread
opening named pipe for read
inside new thread
opening a simple file
simple file opened successfully
simple file closed
然后只有主线程挂起,直到将某些内容回显到namedPipe中。
我们正在努力解决一个不会阻止的变通方法,但这涉及到忙碌的等待,但这并不是很好。 谁能解释这种行为?
解决方法
在Cygwin上,open
系统调用会在整个系统调用期间锁定文件描述符表。这意味着所有open
系统调用实际上都是顺序执行的。
extern "C" int
open (const char *unix_path,int flags,...)
{
. . .
cygheap_fdnew fd; // <-- here
还有cygheap.h
:
class cygheap_fdnew : public cygheap_fdmanip
{
public:
cygheap_fdnew (int seed_fd = -1,bool lockit = true)
{
if (lockit)
cygheap->fdtab.lock (); // <-- here
. . .
我认为没有简单的方法可以解决这个问题,但是我猜至少在有fifo的情况下,一旦创建了描述符,就应该可以解锁fd表(请参见fhandler_fifo
),因为{{3 }}在open
上阻止。您可以在fifo上进一步讨论。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。