pthread блокировка чтения-записи неопределенное поведение

Я наткнулся на неожиданные результаты в тесте на блокировку чтения-записи pthread.

ниже мой код.

#include <iostream>
#include <thread>
#include <pthread.h>

//locks declaration
pthread_rwlock_t       rwlock;

//shared resource
int numbers[20];
int size = 0;void readFrom()
{
int rc;

rc = pthread_rwlock_rdlock(&rwlock);

for(int index = 0; index < size; index++) {
std::cout << numbers[index] <<  " ";
}
std::cout << std::endl;

rc = pthread_rwlock_unlock(&rwlock);
}

void writeTo(int index, int val)
{
int rc;

rc = pthread_rwlock_wrlock(&rwlock);

numbers[index] = val;

size++;

rc = pthread_rwlock_unlock(&rwlock);

}

int main(int argc, char **argv)
{
int rc=0;
std::cout << std::endl;
std::thread threads[25];

rc = pthread_rwlock_init(&rwlock, NULL);

for(int i=0; i<20; ++i) {
threads[i] = std::thread(writeTo, i, i);
if(i % 5 == 0) {
threads[20 + (i / 5)] = std::thread(readFrom);
}
}for(int i=0; i<24; ++i) {
threads[i].join();

}std::cout << "size is " << size << std::endl;threads[24] = std::thread(readFrom);
threads[24].join();
std::cout << std::endl;rc = pthread_rwlock_destroy(&rwlock);
return 0;
}

после нескольких пробежек я иногда нахожу что-то неожиданное. Вот пример:

0 1 2 3 0

Это выход из потока читателя. В основном, это говорит о том, что размер цифр на данный момент 5. в этом случае я ожидаю, что результат будет 0 1 2 3 4.

Кстати, я попытался реализовать дополнение взаимоисключающей блокировки, которая разжигала неожиданное поведение.

Я интересен как решением, так и основной причиной. Кто-нибудь может мне помочь?

любая помощь ценится заранее.

0

Решение

Блокировка чтения / записи просто препятствует одновременной работе двух программ записи или одновременной работы программы записи с читателем. Ни одна из этих вещей не требуется для получения вывода «0 1 2 3 0». Так что нет никаких причин, по которым вы должны считать это неожиданным.

На самом деле, если у вас четыре ядра, «0 1 2 3 0» — это, безусловно, выход, который я ожидаю, по крайней мере, некоторое время. Потоки работают в том порядке, в котором они были запущены, пока все четыре ядра не используются, затем новые потоки должны ждать, пока существующие потоки не завершат свои временные интервалы. Это кажется совершенно разумным для меня.

Если вы можете детализировать мыслительный процесс, который заставил вас думать, что «0 1 2 3 0» является неожиданным, мы можем указать на конкретный недостаток в нем.

Кстати, для такого приложения вы должны просто использовать обычную блокировку. Использование блокировки чтения / записи имеет смысл только тогда, когда операции чтения значительно превосходят числовые операции записи, или когда читатели должны удерживать блокировку относительно долгое время.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]