Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Использование общей памяти и синхронизация процессов
Существование функций распределения памяти в этом томе стандарта IEEE Std 1003.1-2001 дает приложению возможность выделять память объектам синхронизации из того раздела, который доступен многим процессам (а следовательно, и потокам многих процессов). Чтобы реализовать такую возможность при эффективной поддержке обычного (т.е. однопроцессорного) случая, был определен атрибут process-shared. Если реализация по д держивает опцию _POSIX_THREAD_PROCESS_SHARED, то атрибут process-shared м ожно использовать для индикации того, что к мьютексам или условным переменным могут получать доступ потоки сразу нескольких процессов. Для того чтобы объекты синхронизации по у м олчанию создавались в са м ой эффективной фор м е, для атрибута process-shared в качестве стандартного было выбрано значение PTHREAD_PROCESS_PRIVATE. Пере м енные синхронизации, которые инициализированы значение м PTHREAD_PROCESS_PRIVATE атрибута process-shared, м огут обрабатываться потока м и только в то м процессе, в которо м была выполнена инициализации этих пере м енных. Пере м енные синхронизации, которые инициализированы значение м PTHREAD_PROCESS_SHARED атрибута process-shared, м огут обрабатываться любым потоком в любом процессе, который имеет к ним доступ. В частности, эти процессы могут существовать независимо от процесса инициализации. Например, следующий код реализует простой семафор-счетчик в общедоступном файле, который может быть использован многими процессами. /* sem.h */ struct semaphore { pthread_mutex_t lock; pthread_cond_t nonzero; unsigned count; }; typedef struct semaphore semaphore_t; semaphore_t *semaphore_create (char *semaphore_name); semaphore_t *semaphore_open (char *semaphore_name); void semaphore_post (semaphore_t *semap); void semaphore_wait (semaphore_t *semap); void semaphore_close (semaphore_t *semap); /* sem.c */ #include < sys/types.h> #include < sys/stat.h> #include < sys/mman.h> #include < fcntl.h> #include < pthread.h> #include 11 sem.h» semaphore_t * semaphore_create (char * semaphore_name) t int fd; semaphore_t * semap; pthread_mutexattr_t psharedm; pthread_condattr_t psharedc; fd = open(semaphore_name, O_RDWR | O_CREAT | O_EXCL, Оббб); if (fd < 0) return (NULL); (void) ftruncate (fd, sizeof (semaphore_t)); (void) pthread_mutexattr_init (& psharedm); (void) pthread_mutexattr_setpshared(& psharedm, PTHREAD_PROCESS_SHARED); (void) pthread_condattr_init (& psharedc); (void) pthread_condattr_setpshared (& psharedc PTHREAD_PROCESS_SHARED); semap = (semaphore_t *) mmap (NULL, sizeof (semaphore_t), PR0T_READ | PROT_WRITE, MAP_SHARED, fd, О); close (fd); (void) pthread_mutex_init (& semap-> lock, & psharedm); (void) pthread_cond_init (& semap-> nonzero, & psharedc); semap-> count = 0; return (semap); } semaphore_t * semaphore_open (char *semaphore_name) { int fd; semaphore_t *semap; fd = open (semaphore_name, O_RDWR, 0666); if (fd < 0) return (NULL); semap = (semaphore_t *) mmap (NULL, sizeof (semaphore_t), PROT_READ | PROT_WRITE, MAP_SHARED, f d, 0); close (fd); return (semap); } void semaphore_post (semaphore_t *semap) { pthread_mutex_lock (& semap-> lock); if (semap-> count == 0) pthread_cond_signal (& semapx-> nonzero); semap-> count++; pthread_mutex_unlock (& semap-> lock); } void semaphore_wait (semaphore_t * semap) { pthread_mutex_lock (& semap-> lock); while (semap-> count == 0) pthread_cond_wait (& semap-> nonzero, & semap-> lock); semap-> count--; pthread_mutex_unlock (& semap-> lock); } void semaphore_close (semaphore_t *semap) { munmap ((void *) semap, sizeof (semaphore_t)); } Следующий код обеспечивает выполнение трех отдельных процессов, которые создают семафор в файле /tmp/semaphore, отправляют сигналы и ожидают его освобождения. После того как семафор создан, программы сигнализации и ожидания инкрементируют и декрементируют счетчик семафора, несмотря на то, что они сами не инициализировали семафор. /* create.c */ # include «pthread. h» #include «sem.h» int main() { semaphore_t * semap; semap = semaphore_create («/ tmp/semaphore»); if (semap == NULL) exit(l); semaphore_close (semap), -return (0); } /* post */ # include «pthread. h» #include «sem.h» int main() { semaphore_t *semap; semap = semaphore_open (" /tmp/semaphore»); if (semap == NULL) exit (1); semaphore_post (semap); semaphore_close (semap); return (0); } /* wait */ #include «pthread.h» #include «sem.h» int main () { semaphore_t *semap; semap = semaphore_open (" /tmp/semaphore 11); if (semap == NULL) exit (1); semaphore_wait (semap); semaphore_close (semap); return (0); }
|