Linux 带有Errno的竞赛条件
我们应该如何处理系统全局变量(如UNIX中的errno)的竞争条件?我看了Tanenbaum的现代操作系统(第四版,第117页),它说使用私有全局变量。所以,基本上,为全局变量分配一些内存块,并将其作为参数传递给每个过程。但这如何解决问题呢 最好的选择就是不要使用全局变量。编写可重入函数,让用户传递正确类型的变量(通常在C语言中,它是指向变量的指针),并使用它。例如,请参见 如果它是一个全局变量,您可以控制它,因为它在用户代码中,并且由于某种原因您无法避免使用它,那么就有了Linux 带有Errno的竞赛条件,linux,multithreading,unix,parallel-processing,operating-system,Linux,Multithreading,Unix,Parallel Processing,Operating System,我们应该如何处理系统全局变量(如UNIX中的errno)的竞争条件?我看了Tanenbaum的现代操作系统(第四版,第117页),它说使用私有全局变量。所以,基本上,为全局变量分配一些内存块,并将其作为参数传递给每个过程。但这如何解决问题呢 最好的选择就是不要使用全局变量。编写可重入函数,让用户传递正确类型的变量(通常在C语言中,它是指向变量的指针),并使用它。例如,请参见 如果它是一个全局变量,您可以控制它,因为它在用户代码中,并且由于某种原因您无法避免使用它,那么就有了 如果在您使用的库中它
如果在您使用的库中它是全局的,但无法更改,那么您必须确保它的任何使用都受到互斥的保护。正如jww所链接的,在大多数支持多线程的标准库中,都采取了一些措施,以确保系统全局的
errno
在多线程环境中是正常的。在今天这个时代,一个图书馆如果不把这件事整理出来,就必须被认为是“没有帮助的”
在多线程库出现之前的糟糕日子里,对标准库函数的调用(对errno
等有副作用)必须使用信号量进行保护。约克
在现代GCC中,有一个扩展线程:
\u线程长myThreadPrivateLong代码>
其他编译器可能也有类似的功能。在我自己的代码中,我偶尔会发现这很有用
当然,其他系统全局变量,如stdin
,stdout
,stderr
不是线程专用的。这毫无意义,因为一个进程只有一个tty
(唉*)。在glibc上,采取了一些措施来确保对stdout
的多线程访问是半正常的,在glibc遇到EOL后,像printf()
这样的函数在实际输出到stdout
之前通过管道进行缓冲。结果是,同时调用printf()
的两个线程的输出行将被分隔。在过去,对printf()
的两个调用所输出的字符会被混淆成一团不可读的乱码。您仍然可以通过同时调用fprintf(stderr,…)
得到这个结果,因为stderr
没有缓冲
*我说唉,因为如果有特定于线程的stdout,并且终端应用程序每个线程都有一个终端选项卡,那就太好了。对用户不是很有用,但有时对开发人员很有用。能够看到单个线程在做什么是很有用的 可能的副本等,好的。但是,在整个系统或流程中唯一的其他静态变量呢?