Reader Preferred и Writer Preferred в многопоточности чтения-записи - PullRequest
0 голосов
/ 21 декабря 2011

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

Ужасная попытка стерта

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

Reader Preferred:

Переменные:

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_);
}

Writer Preferred:

Переменные:

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_);
}

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

Ответы [ 2 ]

2 голосов
/ 21 декабря 2011

В качестве подсказки я не думаю, что

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

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

2 голосов
/ 21 декабря 2011

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...