Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Примеры. Следующий код представляет собой пример использования примитивов потока для реализации блокировки чтения-записи (с приоритетом для записи) с возможностью
Следующий код представляет собой пример использования примитивов потока для реализации блокировки чтения-записи (с приоритетом для записи) с возможностью отмены. typedef struct { pthread_mutex_t lock; pthread_cond_t rcond, wcond; int lock_count; /* lock_count < 0.. Удерживается записывающим потоком. */ /* lock_count > 0.. Удерживается lock_count считывающими * потоками. */ /* lock_count = 0.. Ничем не удерживается. */ int waiting_writers; /* Счетчик ожидающих записывающих * потоков. */ } rwlock; void waiting_reader_cleanup (void, *arg) { rwlock *1; 1 = (rwlock *) arg; pthread_mutex_unlock (& l-> lock); } void lock_for_read (rwlock *1) { pthread_mutex_lock (& l-> lock); pthread_cleanup_push (waiting_reader_cleanup, 1); while ((l-> lock_count < 0) & & (l-> waiting_writers! = 0)) pthread_cond_wait (& l-> rcond, & l-> lock); l-> lock_count++; /* * Обратите внимание на то, что функция pthread_cleanup_pop() * выполняет здесь фyнкциюwaiting_reader_cleanup(). */ pthread_cleanup_pop(l); } void release_read_lock (rwlock *1) { pthread_mutex_lock (& l-> lock); if (--l-> lock_count == 0) pthread_cond_signal (& l-> wcond); pthread_mutex_unlock (1); void waiting_writer_cleanup (void *arg) { rwlock *1; 1 = (rwlock *) arg; if ((—l-> waiting_writers == О) & & (l-> lock_count > = 0)) { /* * Это происходит только в случае отмены потока. */ pthread_cond_broadcast (& l-> wcond); } pthread_mutex_unlock (& l-> lock); } void lock_for_write (rwlock *1) { pthread_mutex_lock (& l-> lock), -l-> waiting_writers++; pthread_cleanup_push (waiting_writer_cleanup, 1); while (l-> lock_count! = О) pthread_cond_wait (& l-> wcond, & l-> lock); l-> lock_count = -1; /* * Обратите внимание на то, что функция pthread_cleanup_pop() * выполняет здесь функцию waiting_writer_cleanup(). */ pthread_cleanup_pop (1); } void release_write_lock (rwlock *1) { pthread_mutex_lock (& l-> lock); l-> lock_count = 0; if (l-> waiting_writers == О) pthread_cond_broadcast (& l-> rcond) else pthread_cond_signal (& l-> wcond); pthread_mutex_unlock (& l-> lock); } /* * Эта функция вызывается для инициализации блокировки * чтения-записи. */ void initialize_rwlock (rwlock *1) { pthread_mutex_init (& l-> lock, pthread_mutexattr_default); pthread_cond_init (& l-> wcond, pthread_condattr_default); pthread_cond_init (& l-> rcond, pthread_condattr_default); l-> lock_count = О; l-> waiting_writers = О; \ Приложение Б 559 } reader_thread() { lock_for_read (& lock); pthread_cleanup_push (release_read_lock, & lock); /* * Поток устанавливает блокировку для чтения. */ pthread_cleanup_pop (1); } writer_thread() { lock_for_write (& lock); pthread_cleanup_push (release_write_lock, & lock); /* * Поток устанавливает блокировку для записи. */ pthread_cleanup_pop (1); }
|