使用std::forward_list擦除和插入时是否存在数据争用?例如,我有一个线程只在列表末尾添加新元素,而另一个线程遍历(相同)列表并可以从中删除元素。
根据我对链表的了解,每个元素都有一个指向下一个元素的指针,因此如果我在插入新元素的同时删除最后一个元素,这会导致数据竞争还是这些容器的工作方式不同(或者它们处理这种可能性)?
如果是数据竞赛,有没有(简单快速)的方法可以避免这种情况?(注意:插入的线程是两者中速度最关键的。)
除非您使用的STL版本明确声明它是线程安全的,否则否,容器不是线程安全的。
默认情况下,使通用容器线程安全是罕见的,因为它会对不需要线程安全访问容器的用户造成性能损失,这是迄今为止的正常使用模式。
如果线程安全对您来说是一个问题,那么您需要用锁包围代码,或者使用专门为多线程访问设计的数据结构。
否,无论是forward_list
还是任何其他STL容器对于写入都是线程安全的。您必须提供同步,以便在写入发生时没有其他线程对容器进行读取或写入。只有同时读取才是安全的。
最简单的方法是使用互斥锁在插入发生时锁定对容器的访问。以可移植的方式执行此操作需要C 11(std::互斥锁)或特定于平台的功能(Windows中的互斥锁,也许Linux /Unix的pthread)。
标准C库容器有线程安全保证,但它们往往不是人们会考虑线程安全保证(即,人们期望错误的错误)。标准库容器的线程安全保证大致如下(相关第17.6.5.9节[res.on.data.races]):
const
成员函数加上使用一些非const
成员只读取数据(线程安全的读取数据不是任何容器关心,即23.2.2[container.requirements.dataraces]指定可以在容器不引入数据竞争的情况下更改元素)。 也就是说,读取容器的一端并写入另一端不是线程安全的!事实上,即使实际的容器更改不会立即影响读取器,在将一段数据从一个线程传递到另一个线程时,您始终需要某种形式的同步。也就是说,即使您可以保证使用者不会erase()
生产者当前的节点insert()
s,也会出现数据竞争。
我的任务是创建函数来添加和删除链表中的节点,输入数据为int,字符为with函数调用。我不确定我做错了什么。我得到的唯一错误是:退出时返回代码为-11(SIGSEGV)。还有一个编译器方法:main。cpp:在函数“void listInsertValue(ListNode)”中* 感谢任何帮助。谢谢!
我有一个在Oracle 11g DB上运行的insert语句,如下所示: 这里有一个处理PostgreSQL的类似问题。但是,由于Oracle序列由所有会话共享,所以我不能相信DB会给出当前会话中最后插入的值。
null
我试图编写一个方法来插入一个节点和移除链表后面的一个节点。下面是我在其中编写方法的主类。它们在底部(insertBack和removeBack): 可能有格式错误,因为我粘贴到这里,但我仍然试图找出如何使用这个网站。当我运行如下所示的驱动程序类时,我会得到如下所示的结果。 有人能帮我弄清楚为什么我的removeFront和removeBack方法不起作用吗?
问题内容: 我一直在假设线程安全也不是线程安全,但是在最近的一次讨论中,一位同事告诉我线程安全。 因此,我做了一些研究,却一无所获。很多人认为它是线程安全的,很多人认为它不是线程安全的。而且,最重要的是,文档没有以一种或另一种方式说任何话,不是为了,甚至不是。 那是什么呢? 问题答案: 这是指向Java 7 中Calendar和GregorianCalendar的源代码的链接。 如果阅读该代码,您
我必须编写一个双链接列表,我正在尝试实现方法,该方法接受一个参数obj,遍历列表并删除包含元素obj的每个节点。 我面临的问题是,我从前面遍历链表,当我找到包含obj元素的节点时,我会在包含obj元素的节点前后更改节点的下一个/上一个指针。然而,我并没有删除带有obj本身的节点,据我所知,c没有垃圾收集,所以带有obj的节点仍然悬在空中。我如何删除它? 我的擦除()