我遇到了“一些函数本质上是线程安全的,例如memcpy()__”。
Wikipedia将“线程安全”定义为:
一段代码是线程安全的,如果它只以保证同时由多个线程安全执行的方式操作共享数据结构。
好的。但本质上意味着什么呢?这与继承有关吗?
发布于 2014-04-07 09:33:10
与继承无关。这是一种非正式的表达方式,意思更像
“某些功能本质上是线程安全的”。例如,一个没有
触摸任何共享值/状态无论如何都是线程安全的,即“本质上是线程安全的”。
发布于 2014-04-07 09:33:17
在这种情况下,我把它解释为“没有为实现它而设计,它仍然是线程安全的”。
虽然这些词语当然是相关的,但与继承的概念没有直接联系。当然,这不是面向对象编程意义上的继承的一个例子。这只是一个函数,它的核心特性是线程安全。
当然,memcpy()固有的线程安全也没有什么神奇之处。任何没有内部状态或“共享”副作用的函数都是这样的,这就是为什么functional programming (所有函数都被认为是“纯的”和缺乏副作用)能够很好地用于并行编程。
在实践中,典型的计算机很难在没有副作用的情况下完成“真正的工作”,特别是I/O很大程度上是由其副作用来定义的。因此,即使是纯函数式语言也往往有一些非功能的角落。
Update:当然,memcpy()不是没有副作用的,它的核心目的是操纵内存,如果在线程之间共享的话,内存肯定是不安全的。假设必须是,只要目标区域是不同的,一个或多个线程是否并行运行memcpy()并不重要。
将此与例如printf()进行对比,后者在单个输出流(用于流程)上生成字符。它必须显式地实现(按照POSIX的要求)才能是线程安全的,而memcpy()则不是。
发布于 2014-04-07 13:27:36
一个固有的线程安全功能,是安全的,而不必做出任何有关线程的具体设计决定,它仅仅是因为它所执行的任务而是线程安全的,而不是为了强制线程安全而重新设计。假设我写了一个非常简单的函数:
int cube(int x)
{
return x*x*x;
}它本质上是线程安全的,因为它无法从共享内存中读取或写入共享内存。但是,我也可以通过特定的设计和同步来创建一个不是线程安全的函数,而是使它成为线程安全的函数。假设我有和以前相似的功能:
void cubeshare()
{
static int x;
x = x * x * x;
printf("%l", x);
}这不是线程安全的,它完全有可能在每次使用之间有x变化的值(实际上,这在现实中是不太可能的,因为x会被缓存,但让我们说我们没有做任何优化)。
然而,我们可以让这个线程像这样安全(这是伪代码,一个真正的互斥对象更复杂):
void cubesharesafe(mutex foo)
{
static int x;
lockmutex(foo);
x = x * x * x;
printf("%l", x);
unlockmutex(foo);
}然而,这并不是内在的线程安全,我们正在迫使它通过重新设计。实际的例子往往比这复杂得多,但我希望这能给出一个尽可能简单的想法。如果您有任何问题,请评论如下。
https://stackoverflow.com/questions/22908520
复制相似问题