Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Filesystems 套接字描述符关闭两次错误对多线程程序的影响_Filesystems_C_Multithreading - Fatal编程技术网

Filesystems 套接字描述符关闭两次错误对多线程程序的影响

Filesystems 套接字描述符关闭两次错误对多线程程序的影响,filesystems,c,multithreading,Filesystems,C,Multithreading,在单线程程序中,这是一个明显的错误:“fd”被关闭了两次。这个bug对多线程程序有什么影响?它可能是任何东西。在多线程程序中,没有可靠的方法来预测污染共享资源的影响 最明显的问题是,您可能会在第一次关闭之后但在第二次关闭之前关闭另一个线程为某些重要目的打开的套接字。但是,如果不理解这些代码,就无法预测某些片段代码在这些情况下会做什么 仅举一个例子,您可能会提前终止与远程服务器的连接,导致服务器处理部分请求而不是完整请求。如果不了解所使用的协议,就无法知道部分请求可能会做什么 下面是更糟糕的情况:

在单线程程序中,这是一个明显的错误:“fd”被关闭了两次。这个bug对多线程程序有什么影响?

它可能是任何东西。在多线程程序中,没有可靠的方法来预测污染共享资源的影响

最明显的问题是,您可能会在第一次关闭之后但在第二次关闭之前关闭另一个线程为某些重要目的打开的套接字。但是,如果不理解这些代码,就无法预测某些片段代码在这些情况下会做什么

仅举一个例子,您可能会提前终止与远程服务器的连接,导致服务器处理部分请求而不是完整请求。如果不了解所使用的协议,就无法知道部分请求可能会做什么

下面是更糟糕的情况:

此线程关闭描述符4。 日志线程打开一个本地文件并获取描述符4。 此线程再次关闭描述符4。虫子。 另一个线程打开到不受信任服务器的套接字连接,并获取描述符4。 日志线程再次运行,并将敏感信息写入描述符4。
哎呀。我们刚刚向一个随机远程连接发送了高度敏感的信息。

一方面,关闭一个已经关闭的fd只会使您的第二次关闭返回EBADF fd不是有效的打开文件描述符。这是无害的

另一方面,在多线程程序中,没有任何东西可以保证fd不会被重用,例如,另一个线程在两个关闭调用之间同时调用open。在这种情况下,您会意外地关闭最近打开的文件,这是有害的

这个bug在多线程程序中会产生什么影响

99.999%的时间,什么都没有;第二次关闭调用将失败,errno设置为EBADF,生命将继续

另一个.001%的情况下,另一个线程将在线程中执行两个close调用之间的那一瞬间运行并调用open,而另一个线程的open调用将返回与fd局部变量设置为相同的文件描述符值,因为在关闭文件描述符值后,允许运行时重新使用文件描述符值。。。然后线程将再次运行,对closefd的第二次调用将关闭另一个线程的套接字


此时,使用该文件描述符的另一个线程的网络调用将开始在EBADF中出错,因为它试图使用一个现已关闭的文件描述符,你将花费数小时/数天/数周的不愉快时间来追踪为什么你的程序的网络似乎会在一个月内随机失败。

与单线程程序没有什么不同:第二次关闭调用将失败…@prog fh如果另一个线程在两次关闭调用之间打开一个文件或套接字并得到相同的结果会怎么样descriptor?@DavidSchwartz如果以任何方式使用dup(例如)打开同一资源,则关闭调用将使第一个文件描述符不可用,但另一个文件描述符仍可以访问同一资源。但这两个结束调用不适用于同一个文件描述符。啊。。。好吧,我明白了,你说的是比赛条件。。。好吧,任何事情都有可能发生,那么为什么这个问题是特定的呢?@prog fh Right。此代码可能是与任何其他线程可能正在运行的任何其他代码竞争条件的一半。谁知道比赛情况会怎么样?哦,比那糟糕多了。它们可能不会出错,因为另一个线程可能会打开不同的文件或套接字并获得相同的描述符。他们可能会成功并将私有信息发送到不受信任的目标。1坏线程关闭描述符4。2受害者线程打开描述符4。3坏线程再次关闭描述符4。4另一个受害者线程打开描述符4。5第一个受害者线程现在写入连接,第二个受害者线程打开时认为它正在写入它打开的任何东西。
fd = open("file", O_RDONLY);
if (fd < 0) exit(1);

while((res = read(fd, buf, sizeof(buf)))){
if (res < 0){
close(fd);
fprintf(stderr, "Read error!\n");
break;
} else {
printf("Read %zd bytes\n", res);
}
}
close (fd);