c – rand_r是否真的是线程安全的?

c – rand_r是否真的是线程安全的?,第1张

概述好吧,rand_r函数应该是一个线程安全的函数.但是,通过它的实现,我无法相信它本身不能被其他线程改变. 假设两个线程将使用相同的变量种子同时调用rand_r. 所以会发生读写比赛. 由glibc实现的代码rand_r如下所示.谁知道为什么rand_r被称为线程安全? int rand_r (unsigned int *seed) { unsigned int next 好吧,rand_r函数应该是一个线程安全的函数.但是,通过它的实现,我无法相信它本身不能被其他线程改变.
假设两个线程将使用相同的变量种子同时调用rand_r.
所以会发生读写比赛.
由glibc实现的代码rand_r如下所示.谁知道为什么rand_r被称为线程安全?
int    rand_r (unsigned int *seed)    {      unsigned int next = *seed;      int result;      next *= 1103515245;      next += 12345;      result = (unsigned int) (next / 65536) % 2048;      next *= 1103515245;      next += 12345;      result <<= 10;      result ^= (unsigned int) (next / 65536) % 1024;      next *= 1103515245;      next += 12345;      result <<= 10;      result ^= (unsigned int) (next / 65536) % 1024;      *seed = next;      return result;    }
解决方法 您可以考虑三个级别的线程安全性,为了便于参考,我将在此处编号.

1)根本不是线程安全的.从多个线程同时调用该函数是不安全的.例如,strtok.

2)相对于系统的线程安全.如果不同的调用对不同的数据进行 *** 作,则可以安全地从多个线程同时调用该函数.例如,rand_r,memcpy.

3)关于数据的线程安全.从多个线程同时调用该函数是安全的,甚至可以对相同的数据执行 *** 作.例如pthread_mutex_lock.

rand_r在2级,C语境中的约定(特别是在POSIX规范中)是调用这个“线程安全”.

在其他一些语言中,例如Java,约定是将级别3称为“线程安全”,将其他所有语言称为“非线程安全”.所以例如java.util.Vector是“线程安全的”而java.util.ArrayList是“非线程安全的”.当然java.util.ArrayList的所有方法都是2级.因此,来自Java的程序员可能会自然地将rand_r和memcpy称为“非线程安全”.

在C中,约定是不同的,可能是因为内部同步的数据结构很少开始.在C的上下文中,您可能会问“文件是否处于线程安全?”,并且正在讨论第3级,但在询问“这个函数是否是线程安全的?”时这通常意味着2级.

总结

以上是内存溢出为你收集整理的c – rand_r是否真的是线程安全的?全部内容,希望文章能够帮你解决c – rand_r是否真的是线程安全的?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1237834.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存