问题描述
我有一个 std :: deque< std :: pair< CustomObj,int>>
,在启动并发块时大小不变.
I have a std::deque<std::pair<CustomObj, int>>
that doesn't change in size when starting the concurrent block.
并发块读取 deque
的每个 CustomObj
并设置 int
.
The concurrent block reads each CustomObj
of the deque
and sets the int
.
我可以保证双端队列不会更改大小,因此不会重新分配,并且每个线程将仅访问双端队列的内存块,而不会访问其他线程的内存块.
I can guarantee that the deque won't change size therefore it won't reallocate, and that each thread will only access a memory chunk of the deque but not the other thread's.
是否会导致未定义的行为并发读写?我应该将文字和阅读放在互斥区吗?
Does it lead to undefined behaviour reading and writing concurrently? Should I put the writing and reading in a mutual exclusion zone?
推荐答案
令我惊讶的是,当前标准本身实际上对此有一个非常清晰的部分:
Surprisingly to me, there is actually a very clear section about this in the current standard itself:
(C ++ 17,26.2.2容器数据竞赛,2)
(C++17, 26.2.2 Container data races, 2)
- 尽管有20.5.5.9,当同时修改了容器中除
vector< bool>
之外的不同元素中包含的对象的内容时,需要采取一些措施来避免数据争用.
- Notwithstanding 20.5.5.9, Implementations are required to avoid data races when the contents of the contained object in different elements in the same container, excepting
vector<bool>
, are modified concurrently.
此外,您也可以放心调用以下访问器:
Also you are allowed to call the following accessors without worry:
- 为了避免数据争用(20.5.5.9),实现应将以下功能视为:const:
开头,结尾,rbegin,rend,正面,背面,数据,查找,lower_bound,upper_bound,equal_range,位于
并且,除了在关联或无序关联容器中,operator []
.
- For purposes of avoiding data races (20.5.5.9), implementations shall consider the following functions to be const:
begin, end, rbegin, rend, front, back, data, find, lower_bound, upper_bound, equal_range, at
and, except in associative or unordered associative containers,operator[]
.
由于 std :: deque
也不例外,因此可以并发调用这些函数中的任何一个以获取不同的元素并进行修改.只要确保将对容器本身的任何修改与并行访问并修改元素的并行区域正确隔离即可.
Since std::deque
is neither exception, you are fine to concurrently call any of those functions to get different elements and modify them. Just make sure to properly isolate any modifications to the container itself from the parallel region where you concurrently access and modify the elements.
例如,这将是错误的:
std::dequeue<...> dq;
#pragma omp master
{
...
dq.emplace(...);
}
// no implicit barrier here,
// use omp barrier or change to omp single instead of master
#pragma omp for
for (... i; ...)
dq[i].second = compute(dq[i]);
这篇关于是在不同内存位置同时写入std :: deque线程安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!