たぶん私はその考えを正しく理解していませんでしたが、明らかな解決策はstd::atomic
現在の配列インデックスに増分を使用することです。整数型のアトミックは通常、ロックフリーとして実装されます。
ただし、これが当てはまらない場合、またはコンパイラがC ++ 11をサポートしていない場合はInterlockedIncrement
、VSや__sync_fetch_and_add
GCCなどのコンパイラ固有のロックフリー関数に置き換えることができます。
IntelC++コンパイラC++ 11 atomics
の場合はサポートされています。_InterlockedIncrement64
また、ヘッダーファイルから使用することもできます。ia64intrin.h
の147ページを参照してくださいIntel(R) C++ Intrinsics Reference
。
サンプルコード(ここで機能することの証明)
#include <atomic>
#include <thread>
#include <iostream>
const uint max_count = 100;
std::atomic_uint count;
std::string data[max_count];
void thread_func(const char* str)
{
while(true)
{
const uint index = count++;
if(index >= max_count) break;
// Use += to see defect if data was already initialized by other thread
data[index] += str;
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
int main()
{
std::cout << "Atomic counter is lock-free: " <<
(count.is_lock_free() ? "Yes!" : "No!") << std::endl;
std::thread t1(thread_func, "Thread 1");
std::thread t2(thread_func, "Thread 2");
std::thread t3(thread_func, "Thread 3");
t1.join();
t2.join();
t3.join();
for(uint i = 0; i < max_count; ++i)
{
std::cout<< i << ": " << data[i] << std::endl;
}
return 0;
}