Читать «UNIX: взаимодействие процессов» онлайн - страница 318
Уильям Ричард Стивенс
Листинг А.23. Увеличение счетчика с использованием семафоров Posix в памяти
//bench/incr_pxsem1.с
37 void *
38 incr(void *arg)
39 {
40 int i;
41 for (i = 0; i < nloop; i++) {
42 Sem_wait(&shared.mutex);
43 shared.counter++;
44 Sem_post(&shared.mutex);
45 }
46 return(NULL);
47 }
Листинг А.24. Функция main для семафоров Posix, размещаемых в памяти
//bench/incr_pxsem1.с
1 #include "unpipc.h"
2 #define MAXNTHREADS 100
3 int nloop;
4 struct {
5 sem_t mutex; /* размещаемый в памяти семафор */
6 long counter;
7 } shared;
8 void *incr(void *);
9 int
10 main(int argc, char **argv)
11 {
12 int i, nthreads;
13 pthread_t tid[MAXNTHREADS];
14 if (argc != 3)
15 err_quit("usage: incr_pxseml <#loops> <#threads>");
16 nloop = atoi(argv[1]);
17 nthreads = min(atoi(argv[2]), MAXNTHREADS);
18 /* инициализация размещаемого в памяти семафора 0 */
19 Sem_init(&shared.mutex, 0, 0);
20 /* создание всех потоков */
21 Set_concurrency(nthreads);
22 for (i = 0; i < nthreads; i++) {
23 Pthread_create(&tid[i], NULL, incr, NULL);
24 }
25 /* запуск таймера и разблокирование семафора */
26 Start_time();
27 Sem_post(&shared.mutex);
28 /* ожидание завершения всех потоков */
29 for (i = 0; i < nthreads; i++) {
30 Pthread_join(tid[i], NULL);
31 }
32 printf("microseconds: %.0f usec\n", Stop_time());
33 if (shared.counter != nloop * nthreads)
34 printf("error: counter = %ld\n", shared.counter);
35 exit(0);
36 }
18-19 Создается семафор, инициализируемый значением 0. Второй аргумент в вызове sem_init, имеющий значение 0, говорит о том, что семафор используется только потоками вызвавшего процесса.
20-27 После создания всех потоков запускается таймер и вызывается функция sem_post.
Именованные семафоры Posix
В листинге А.26 приведен текст функции main, измеряющей быстродействие именованных семафоров Posix, а в листинге А.25 — соответствующая функция incr.
Листинг А.25. Увеличение общего счетчика с использованием именованного семафора Posix
//bench/incr_pxsem2.c
40 void *
41 incr(void *arg)
42 {
43 int i;
44 for (i = 0; i < nloop; i++) {
45 Sem_wait(shared.mutex);
46 shared.counter++;
47 Sem_post(shared.mutex);
48 }
49 return(NULL);
50 }
Листинг А.26. Функция main для измерения быстродействия именованных семафоров Posix
//bench/incr_pxsem2.с
1 #include "unpipc.h"
2 #define MAXNTHREADS 100
3 #define NAME "incr_pxsem2"
4 int nloop;
5 struct {
6 sem_t *mutex; /* указатель на именованный семафор */
7 long counter;
8 } shared;
9 void *incr(void *);
10 int
11 main(int argc, char **argv)
12 {
13 int i, nthreads;
14 pthread_t tid[MAXNTHREADS];
15 if (argc != 3)
16 err_quit("usage: incr_pxsem2 <#loops> <#threads>");
17 nloop = atoi(argv[1]);
18 nthreads = min(atoi(argv[2]), MAXNTHREADS);
19 /* инициализация именованного семафора 0 */
20 sem_unlink(Px_ipc_name(NAME)); /* ошибка – OK */
21 shared.mutex = Sem_open(Px_ipc_name(NAME), O_CREAT | O_EXCL, FILE_MODE, 0);
22 /* создание всех потоков */