const int SIZE = 20;
struct Node { Node* next; };
std::atomic<Node*> head (nullptr);
void push (void* p)
{
Node* n = (Node*) p;
n->next = head.load();
while (!head.compare_exchange_weak (n->next, n));
}
void* pop()
{
Node* n = head.load();
while (n &&
!head.compare_exchange_weak (n, n->next));
return n ? n : malloc (SIZE);
}
void thread_fn()
{
std::array<char*, 1000> pointers;
for (int i = 0; i < 1000; i++) pointers[i] = nullptr;
for (int i = 0; i < 10000000; i++)
{
int r = random() % 1000;
if (pointers[r] != nullptr) // allocated earlier
{
push (pointers[r]);
pointers[r] = nullptr;
}
else
{
pointers[r] = (char*) pop(); // allocate
// stamp the memory
for (int i = 0; i < SIZE; i++)
pointers[r][i] = 0xEF;
}
}
}
int main(int argc, char *argv[])
{
int N = 8;
std::vector<std::thread*> threads;
threads.reserve (N);
for (int i = 0; i < N; i++)
threads.push_back (new std::thread (thread_fn));
for (int i = 0; i < N; i++)
threads[i]->join();
}
Что не так с этим использованием compare_exchange_weak? Вышеупомянутый код сбрасывается 1 раз в 5 раз с помощью clang ++ (MacOSX).правильное использование compare_exchange_weak
Глава.load() во время аварии будет иметь «0xEFEFEFEFEFEF». pop
походит на malloc и push
- это как бесплатный. Каждый поток (8 потоков) случайным образом распределить или освобождать память от head
Ваш заголовок упоминает 'compare_exchange_weak', но ваш код использует' compare_exchange_strong'. Который из них? –
Сбой для обоих: compare_exchange_weak и compare_exchange_strong. – venkat
Почему вы возвращаете 'malloc (20)' в 'pop()' когда 'n == nullptr'? Разве вы не должны просто возвращать 'nullptr'? – agold