Windows的rand_s线程安全吗?

时间:2020-03-06 14:49:11  来源:igfitidea点击:

就像标题一样。怀疑是这样,但是我在明确声明的任何地方都找不到它。对于这个属性,我不想依靠猜测。

解决方案

我想不出为什么rand_s()甚至rand()都不是线程安全的任何原因。

克里斯说:rand()不是线程安全的,因为它的内部状态是静态的,但是rand_s()应该是线程安全的。

Jeff补充说,在MSVCRT的多线程版本中,rand()的状态保存在线程本地存储中,因此仍然可以。

如果使用CRT的多线程版本,则所有功能都是线程安全的,因为任何特定于线程的信息都存储在TLS中。实际上,rand_s实际上并不使用状态信息,因为它只是调用OS API,因此rand_s不会出现线程安全性问题。但是,rand()依赖于种子值来生成随机数。

Visual Studio附带了运行时库的源代码。尽管其中的某些内容可能很麻烦,但rand_s()非常简单。

rand_s()所做的全部工作是调用ADVAPI32.DLL中的SystemFunction036()以获取随机值。 ADVAPI32.DLL中的任何内容都应该是线程安全的。

就其本身而言,rand_s()以线程安全的方式获取指向该函数的指针。

我不知道rand_s是否是线程安全的,但似乎很可能是这样,因为它似乎使OS往返于熵。 (只要我们链接到VC ++多线程CRT,如果我们链​​接到单线程一个,所有的赌注都是关闭的)

如果Windows CRT支持,则可以尝试调用rand_r,它是rand的posix可重入版本。甚至更好的boost :: random,如果我们已经在使用boost。

考虑到多线程将很快普及,没有人应该在新代码中再使用rand(),而总是尝试使用rand_r / rand_s / boost /各种平台相关的安全rands / etc。