Параллельное и распределенное программирование на С++
Шрифт:
Использование общей памяти и синхронизация процессов
Существование функций распределения памяти в этом томе стандарта 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);
}
Будущие направления
Отсутствуют.
Смотри также
pthread_cond_destroy , pthread_create , pthread_mutex_destroy , pthread_mutexattr_destroy , том Base Definitions стандарта IEEE Std 1003.1-2001,<pthread.h>.
Последовательность внесения изменений
Функции впервые реализованы в выпуске Issue 5. Включены для согласования с расширением POSIX Threads Extension.
Issue 6
Функции pthread_mutexattr_destroy и pthread_mutexattr_init отмечены как часть опции Threads.
Раздел «Ошибки» был отредактирован путем при м енения интерпретации IEEE PASC Interpretation 1003.1с #27.
pthread_mutexattr_getprioceiling, pthread_mutexattr_setprioceiling
Имя
pthread_mutexattr_getprioceiling, pthread_mutexattr_setprioceiling
Синопсис
THR #include <pthread.h> TPP
int pthread_mutexattr_getprioceiling (
const pthread_mutexattr_t *restrict attr, int *restrict prioceiling); int pthread_mutexattr_setprioceiling (
pthread_mutexattr_t *attr, int prioceiling);