memcpy[是否?]和多线程[std::thread from c+;+;11]

memcpy[是否?]和多线程[std::thread from c+;+;11],c,multithreading,memcpy,interval-arithmetic,C,Multithreading,Memcpy,Interval Arithmetic,我使用lot BIAS/Profil(区间代数库)用C/C++编写了一个软件。在我的算法中,我有一个主进程来划分一个域,并将它的一部分提供给从属进程。它们返回关于这些域部分的int规约。阅读有共同的数据,仅此而已 我需要并行化我的代码,但是只要有两个从线程正在运行(或者我猜是更多),并且都在调用这个库的函数,它就会出错。这些segfaults的独特之处在于,gdb很少指示来自两个构建的相同错误行:它取决于线程的速度,如果一个线程更早启动,等等。我已经尝试让线程屈服,直到主线程同意,它才“稳定”错

我使用lot BIAS/Profil(区间代数库)用C/C++编写了一个软件。在我的算法中,我有一个主进程来划分一个域,并将它的一部分提供给从属进程。它们返回关于这些域部分的int规约。阅读有共同的数据,仅此而已

我需要并行化我的代码,但是只要有两个从线程正在运行(或者我猜是更多),并且都在调用这个库的函数,它就会出错。这些segfaults的独特之处在于,gdb很少指示来自两个构建的相同错误行:它取决于线程的速度,如果一个线程更早启动,等等。我已经尝试让线程屈服,直到主线程同意,它才“稳定”错误。我相当确定它来自于对库的memcpy的调用(在gdb回溯之后,我总是在BIAS/Profil函数调用memcpy上结束。公平地说,几乎所有函数在返回结果之前都会调用memcpy到临时对象…)。从我在网上看到的情况来看,memcpy()可能不是线程安全的,这取决于实现(尤其是)。(对于一个只读取共享数据的函数来说似乎很奇怪……或者在写入线程数据时,两个线程占用相同的内存空间?)

为了解决这个问题,我想“替换”(至少对于行为发生变化的测试)对memcpy的调用,以实现互斥框架调用。(类似于mtx.lock();mempcy(…);mtx.unlock();)

第一个问题:我根本不是开发/代码工程师,缺乏很多基础知识。我认为,当我使用一个预构建的BIAS/Profil库时,memcpy就是构建库的系统之一,对吗?如果是这样,如果我尝试在我的系统上从源代码构建库,它会改变什么吗?(我不确定我是否能建立这个库,因此我提出了这个问题。)

第二个问题: 在my string.h中,memcpy由以下语句声明:
\ifndef\uuuuuuuuuuoArch\uoMemcpy
extern void*memcpy(void*,const void*,内核大小)
#endif
和其他一些字符串头(string_64.h,string_32.h)中的形式定义:
#define memcpy(dst,src,len)u inline_memcpy((dst),(src),(len))
或一些更明确的定义,或者只是引用的声明。 它开始变得难看了,但理想情况下,我想创建一个预处理器变量
\define\uuu HAVE\u ARCH\u MEMCPY 1
,以及一个
void*MEMCPY(void*,const void*,\uu kernel\u size\u t)
,它将使用废弃的MEMCPY执行互斥框架的MEMCPY。 这里的想法是避免弄乱库,并使其使用3行代码;)


还有更好的主意吗?(这会让我很开心…

一般来说,您必须使用、、或其他一些保护技术来防止多个线程同时访问非线程安全(非重入)函数。
memcpy()
的一些ANSI C实现不是线程安全的,有些是。(,)


编写线程安全的函数和/或编写能够安全容纳非线程安全函数的线程程序是一个重要的主题。非常可行,但需要仔细阅读该主题。有很多书面材料,至少会帮助你开始问正确的问题。

我认为你不应该专注于记忆,而应该专注于更高层次的功能

如果并行运行线程的处理内存间隔不重叠,则memcpy()是线程安全的。实际上,在memcpy()中只有一个for(;;)循环(进行了大量优化)[至少在glibc中],这就是原因,为什么它在声明中


如果您想知道并行memcpy()线程将做什么,您应该想象通过长指针复制内存的for(;;)循环。

考虑到您的观察,Profil库来自上个千年,并且文档(主页和
Profil2.ps
)甚至不包含“线程”一词,我假设lib不是线程安全的

第一:不,通常
memcpy
是动态链接的libc的一部分(至少现在是这样)。在linux上,检查
lddnameofbiary
,它应该给出一行类似于
libc.so.6=>/lib/i386 linux gnu/libc.so.6
或类似的内容。如果没有:重建。如果是:重建可能会有所帮助,因为还有许多其他因素

除此之外,我认为
memcpy
是线程安全的,只要您不回写数据(即使回写未修改的数据也会造成伤害:)


第二:如果结果证明您必须使用修改过的
memcpy
,还可以考虑
LD\u PRELOAD

C/C++不存在。你用C标记,但是你的标题是C++ + Jens:他可以用C++编写,用C++的文件调用C函数,在PrimIL的老年期和你达成一致,但不是我的选择。(他们在大约3年前确实做了一个x64版本,也许10年后会做一个线程安全的版本?;)1=>
ldd libBias.a
回答
不是一个动态可执行文件
。我想知道其他的LIB,所以我要尝试重建。memcpy应该只读取全局数据,而写入本地数据。。。我找到了你引用的链接(也引用了我自己的话),他说即使在读memcpy的时候也在做一些奇怪的事情。2=>我不知道,非常感谢。让我们说最后的办法。。。谢谢你们的反应!
libBias.a的
.a
结尾表示lib是静态链接的。所以
memcpy
是lib从何时何地构建并构建到其中的。在这种情况下,您应该重建
LD_PRELOAD
在这种情况下不起作用。很抱歉,这是错误的:仍然
memcpy
未包含,并将在生成最终程序时链接进来。(为了证实这一点:如果你做了
ar t libBias.a
,就没有
memcpy.o
)@ryker:我找不到足够的文档