Предпочтение от чтения и записи в многопоточности чтения-записи

Мне дали задание написать реализацию чтения-записи с использованием потоков POSIX. Я хотел бы знать, верна ли моя реализация для обоих случаев:

Ужасная попытка удалена

Попытка номер 2

Предпочитается читатель:

Переменные:

int readersActive_;

sem_t lock_;
sem_t writeLock_;

Реализация:

void PalindromeDatabase::lockReaders()
{
    sem_wait(&lock_);
    {
        ++readersActive_;

        if (readersActive_ == 1)
            sem_wait(&writeLock_);
    }
    sem_post(&lock_);
}

void PalindromeDatabase::unlockReaders()
{
    sem_wait(&lock_);
    {
        --readersActive_;

        if (readersActive_ == 0)
            sem_post(&writeLock_);
    }
    sem_post(&lock_);
}

void PalindromeDatabase::lockWriters()
{
    sem_wait(&writeLock_);
}

void PalindromeDatabase::unlockWriters()
{
    sem_post(&writeLock_);
}

Предпочтительный писатель:

Переменные:

int readersActive_;
int readersWaiting_;

int writersActive_;
int writersWaiting_;

pthread_mutex_t lock_;
pthread_cond_t read_;
pthread_cond_t write_;

Реализация:

void PalindromeDatabase::lockReaders()
{
    pthread_mutex_lock(&lock_);
    {
        if (writersActive_ || writersWaiting_)
        {
            ++readersWaiting_;

            do
            {
                pthread_cond_wait(&read_, &lock_);
            } while(writersActive_ || writersWaiting_);

            --readersWaiting_;
        }

        ++readersActive_;
    }
    pthread_mutex_unlock(&lock_);
}

void PalindromeDatabase::unlockReaders()
{
    pthread_mutex_lock(&lock_);
    {
        --readersActive_;

        if (writersWaiting_)
            pthread_cond_signal(&write_);
    }
    pthread_mutex_unlock(&lock_);
}

void PalindromeDatabase::lockWriters()
{
    pthread_mutex_lock(&lock_);
    {
        if (readersActive_ || writersActive_)
        {
            ++writersWaiting_;

            do
            {
                pthread_cond_wait(&write_, &lock_);
            } while(readersActive_ || writersActive_);

            --writersWaiting_;
        }

        writersActive_ = 1;
    }
    pthread_mutex_unlock(&lock_);
}

void PalindromeDatabase::unlockWriters()
{
    pthread_mutex_lock(&lock_);
    {
        writersActive_ = 0;

        if (writersWaiting_)
            pthread_cond_signal(&write_);
        else if (readersWaiting_)
            pthread_cond_broadcast(&read_);
    }
    pthread_mutex_unlock(&lock_);
}

Треды - это весело, они также заставляют мой мозг болеть. Если я ошибаюсь, пожалуйста, воздержитесь от прямого ответа, но направьте меня в правильном направлении, поскольку это домашнее задание, и я, и другие люди, такие как я, несомненно, выиграют, если найдем решение самостоятельно.


person IAE    schedule 20.12.2011    source источник


Ответы (2)


Ни один из ваших кодов не подходит. Вы должны освободить мьютекс, как только вы получите блокировку чтения. Удерживая мьютекс, вам нужно организовать блокировку писателя. При снятии блокировки чтения необходимо организовать разблокировку записывающего устройства, если снимается последняя блокировка чтения.

В псевдокоде:

read_lock:
1) Получить мьютекс.
2) Увеличить счетчик блокировки чтения.
3) Блокировать условную переменную до тех пор, пока не перестанут записываться.
4) Освободить мьютекс.

read_unlock:
1) Получить мьютекс.
2) Уменьшить счетчик блокировок чтения.
3) Если счетчик блокировок чтения равен нулю, разбудить записывающие устройства.
4) Освободить мьютекс.

write_lock:
1) Получить мьютекс.
2) Если используется приоритет записи, сделать так, чтобы не было новых читателей.
3) Блокировать переменную условия до тех пор, пока не останется активных читателей. (Вам нужно заблокировать освобождение мьютекса, иначе ни один читатель не сможет завершить операцию разблокировки!)

write_unlock:
1) Разбудить ожидающих чтения/записи (что зависит от приоритета, который вы реализуете)
2) Освободить мьютекс.

person David Schwartz    schedule 20.12.2011
comment
@Schwartz: Ничего из этого? Д: Ну, это отстой. Ну что ж, лучше сделать это прямо сейчас, чтобы я учился на своих ошибках. Спасибо за псевдокод, он должен помочь мне получить правильную реализацию. - person IAE; 21.12.2011
comment
@Schwarz: Кстати, не могли бы вы сказать мне, что не так с реализацией Writer Preferred? Из этого учебника в формате pdf () я понял, что все, что вы описали в своем псевдокоде, — это то, что rwlock делает внутри. () www.multicoreinfo.com/research/misc/Pthread-Tutorial-Peter.pdf - person IAE; 21.12.2011
comment
Вы не позволяете двум читателям одновременно, побеждая весь смысл блокировки чтения/записи. - person David Schwartz; 21.12.2011

В качестве намека, я не думаю

    // If I'm the last reader, we can let the writers work.
if (--numberOfReadersActive_)
    pthread_cond_signal(&readersActive_);

делает то, что написано в комментарии. Это также может быть причиной того, что вы получаете тупик.

person antlersoft    schedule 21.12.2011