Книга: UNIX: взаимодействие процессов
Взаимные исключения Posix
Разделы на этой странице:
Взаимные исключения Posix
В листинге А.19 приведены глобальные переменные и функция main пpoгрaммы, измеряющей быстродействие взаимных исключений Posix.
Листинг А.19. Глобальные переменные и функция main для взаимных исключений Posix
//bench/incr_pxmutex1.с
1 #include "unpipc.h"
2 #define MAXNTHREADS 100
3 int nloop;
4 struct {
5 pthread_mutex_t mutex;
6 long counter;
7 } shared = {
8 PTHREAD_MUTEX_INITIALIZER
9 };
10 void *incr(void *);
11 int
12 main(int argc, char **argv)
13 {
14 int i, nthreads;
15 pthread_t tid[MAXNTHREADS];
16 if (argc != 3)
17 err_quit("usage: incr_pxmutex1 <#loops> <#threads>");
18 nloop = atoi(argv[1]);
19 nthreads = min(atoi(argv[2]), MAXNTHREADS);
20 /* блокировка взаимного исключения */
21 Pthread_mutex_lock(&shared.mutex);
22 /* создание потоков */
23 Set_concurrency(nthreads);
24 for (i = 0; i < nthreads; i++) {
25 Pthread_create(&tid[i], NULL, incr, NULL);
26 }
27 /* запуск таймера и разблокирование взаимного исключения */
28 Start_time();
29 Pthread_mutex_unlock(&shared.mutex);
30 /* ожидание завершения работы потоков */
31 for (i = 0; i < nthreads; i++) {
32 Pthread_join(tid[i], NULL);
33 }
34 printf("microseconds: %.0f usecn", Stop_time());
35 if (shared.counter != nloop * nthreads)
36 printf("error: counter = %ldn", shared, counter);
37 exit(0);
38 }
Общие данные
4-9 Совместно используемые потоками данные состоят из взаимного исключения и счетчика. Взаимное исключение инициализируется статически.
Блокирование взаимного исключения и создание потоков
20-26 Основной поток блокирует взаимное исключение перед созданием прочих потоков, чтобы ни один из них не получил это исключение до тех пор, пока все они не будут созданы. Вызывается функция set_concurrency, создаются потоки. Каждый поток выполняет функцию incr, текст которой будет приведен позже.
Запуск таймера и разблокирование взаимного исключения
27-36 После создания всех потоков главный поток запускает таймер и освобождает взаимное исключение. Затем он ожидает завершения всех потоков, после чего останавливает таймер и выводит полное время работы. В листинге А.20 приведен текст функции incr, выполняемой каждым из потоков.
Листинг А.20. Функция incr, выполняемая потоками
//bench/incr_pxmutex1.c
39 void *
40 incr(void *arg)
41 {
42 int i;
43 for (i = 0; i < nloop; i++) {
44 Pthread_mutex_lock(&shared.mutex);
45 shared.counter++;
46 Pthread_mutex_unlock(&shared.mutex);
47 }
48 return(NULL);
49 }
Увеличение счетчика — критическая область кода
44-46 Операция увеличения счетчика осуществляется после получения блокировки на взаимное исключение. После этого взаимное исключение разблокируется.
- Взаимные исключения Posix между процессами
- 7.2. Взаимные исключения: установка и снятие блокировки
- 1.2.7. Исключения
- Исключения и обработчики исключений
- 9.1.6.1. Использование функций POSIX: wait() и waitpid()
- Posix
- 14.2.2. Блокировка POSIX: fcntl() и lockf()
- 12.6.2. Функции POSIX: random() и srandom()
- Восстановление в POSIX
- 2.1.1. Соглашения POSIX
- 2.3.3.2. Длинные опции в стиле POSIX
- 8.3.1. Стиль POSIX: statvfs() и fstatvfs()