gpt4 book ai didi

c++ - Cygwin-打开命名的fifo时导致阻塞,导致另一个线程在打开常规文件时阻塞

转载 作者:行者123 更新时间:2023-12-02 10:10:38 24 4
gpt4 key购买 nike

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 syscall在整个syscall期间锁定文件描述符表。这意味着所有open系统调用实际上都是顺序的。
参见 syscalls.cc/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表,因为 fifo会阻塞 fhandler_fifo。您可以在 cygwin-developers上进一步讨论。

关于c++ - Cygwin-打开命名的fifo时导致阻塞,导致另一个线程在打开常规文件时阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63691187/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com