- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания UNIX: взаимодействие процессов - Уильям Стивенс
Шрифт:
Интервал:
Закладка:
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 /* создание всех потоков */
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 Sem_post(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 Sem_unlink(Px_ipc_name(NAME));
38 exit(0);
39 }
Семафоры System V
Функция main программы, измеряющей быстродействие семафоров System V, приведена в листинге А.27, а функция incr показана в листинге А.28.
Листинг А.27. Функция main для измерения быстродействия семафоров System V//bench/incr_svsem1.c
1 #include "unpipc.h"
2 #define MAXNTHREADS 100
3 int nloop;
4 struct {
5 int semid;
6 long counter;
7 } shared;
8 struct sembuf postop, waitop;
9 void *incr(void *);
10 int
11 main(int argc, char **argv)
12 {
13 int i, nthreads;
14 pthread_t tid[MAXNTHREADS];
15 union semun arg;
16 if (argc != 3)
17 err_quit("usage: incr_svseml <#loops> <#threads>");
18 nloop = atoi(argv[1]);
19 nthreads = min(atoi(argv[2]), MAXNTHREADS);
20 /* создание семафора и инициализация его значением 0 */
21 shared.semid = Semget(IPC_PRIVATE, 1, IPC_CREAT | SVSEM_MODE);
22 arg.val =0;
23 Semctl(shared.semid, 0, SETVAL, arg);
24 postop.sem_num = 0; /* инициализация двух структур semop */
25 postop.sem_op = 1;
26 postop.sem_flg = 0;
27 waitop.sem_num = 0;
28 waitop.sem_op = –1;
29 waitop.sem_flg = 0;
30 /* создание всех потоков */
31 Set_concurrency(nthreads);
32 for (i = 0; i < nthreads; i++) {
33 Pthread_create(&tid[i], NULL, incr, NULL);
34 }
35 /* запуск таймера и разблокирование семафора */
36 Start_time();
37 Semop(shared.semid, &postop, 1); /* up by 1 */
38 /* ожидание завершения всех потоков */
39 for (i = 0; i < nthreads; i++) {
40 Pthread_join(tid[i], NULL);
41 }
42 printf("microseconds: %.0f usecn", Stop_time());
43 if (shared.counter != nloop * nthreads)
44 printf("error: counter = %ldn", shared, counter);
45 Semctl(shared.semid, 0, IPC_RMID);
46 exit(0);
47 }
Листинг А.28. Увеличение общего счетчика с использованием семафоров System V//bench/incr_svsem1.c
48 void *
49 incr(void *arg)
50 {
51 int i;
52 for (i = 0; i < nloop; i++) {
53 Semop(shared.semid, &waitop, 1);
54 shared.counter++;
55 Semop(shared.semid, &postop, 1);
56 }
57 return(NULL);
58 }
20-23 Создается семафор с одним элементом, значение которого инициализируется нулем.
24-29 Инициализируются две структуры semop: одна для увеличения семафора, а другая для ожидания его изменения. Обратите внимание, что поле sem_flg в обеих структурах имеет значение 0: флаг SEM_UNDO не установлен.
Семафоры System V с флагом SEM_UNDOЕдинственное отличие от пpoгрaммы из листинга А.27 заключается в том, что поле sem_flg структур semop устанавливается равным SEM_UNDO, а не 0. Мы не приводим в книге новый листинг с этим небольшим изменением.
Блокировка записей fcntl
Последняя пpoгрaммa использует fcntl для синхронизации. Функция main приведена в листинге А.30. Эта программа будет выполняться успешно только в том случае, если количество потоков равно 1, поскольку блокировка fcntl предназначена для использования между процессами, а не между потоками одного процесса. При указании нескольких потоков каждый из них всегда имеет возможность получить блокировку (то есть вызовы writew_lock не приводят к остановке потока, потому что процесс уже является владельцем блокировки), и конечное значение счетчика оказывается неправильным.
Функция incr, использующая блокировку записей, приведена в листинге А.29.
Листинг А.29. Увеличение общего счетчика с использованием блокировки записей fcntl//bench/incr_fcntl1.e
44 void *
45 incr(void *arg)
46 {
47 int i;
48 for (i = 0; i < nloop; i++) {
49 Writew_lock(shared.fd, 0, SEEK_SET, 0);
50 shared.counter++;
51 Un_lock(shared.fd, 0, SEEK_SET, 0);
52 }
53 return(NULL);
54 }
Листинг А.30. Функция main для измерения производительности блокировки fcntl//bench/incr_fcntl1.e
4 #include "unpipc.h"
5 #define MAXNTHREADS 100
6 int nloop;
7 struct {
8 int fd;
9 long counter;
10 } shared;
11 void *incr(void *);
12 int
13 main(int argc, char **argv)
14 {
15 int i, nthreads;
16 char *pathname;
17 pthread_t tid[MAXNTHREADS];
18 if (argc != 4)
19 err_quit("usage: incr_fcntll <pathname> <#loops> <#threads>");
20 pathname = argv[1];
21 nloop = atoi(argv[2]);
22 nthreads = min(atoi(argv[3]), MAXNTHREADS);
23 /* создание файла и получение блокировки на запись */
24 shared.fd = Open(pathname, O_RDWR | O_CREAT | O_TRUNC, FILE_MODE);
25 Writew_lock(shared.fd, 0, SEEK_SET, 0);
26 /* создание всех потоков */
27 Set_concurrency(nthreads);
28 for (i = 0; i < nthreads; i++) {
29 Pthread_create(&tid[i], NULL, incr, NULL);
30 }
31 /* запуск таймера и снятие блокировки на запись */
32 Start_time();
33 Un_lock(shared.fd, 0, SEEK_SET, 0);
34 /* ожидание завершения всех потоков */
35 for (i = 0; i < nthreads; i++) {
36 Pthread_join(tid[i], NULL);
37 }
38 printf("microseconds: %.0f usecn", Stop_time());
39 if (shared.counter != nloop * nthreads)
40 printf("error: counter = %ldn", shared.counter);
41 Unlink(pathname);
42 exit(0);
43 }
15-19 Полное имя создаваемого и используемого для блокировки файла принимается в качестве аргумента командной строки. Это позволяет измерять скорость работы для разных файловых систем. Можно ожидать, что программа будет работать гораздо медленнее при использовании NFS (если она вообще будет работать, то есть если сервер и клиент NFS поддерживают блокировку записей NFS).
А.6. Синхронизация процессов: программы
В программах предыдущего раздела счетчик использовался несколькими потоками одного процесса. При этом он представлял собой глобальную переменную. Теперь нам нужно изменить эти программы для измерения скорости синхронизации различных процессов.
Для разделения счетчика между родительским процессом и дочерними мы помещаем его в разделяемую память, выделяемую функцией my_shm, показанной в листинге А.31.
Листинг А.31. Выделение разделяемой памяти под родительский и дочерние процессы//lib/my_shm.c
1 #include "unpipc.h"
2 void *
3 my_shm(size_t nbytes)
4 {
5 void *shared;
6 #if defined(MAP_ANON)
7 shared = mmap(NULL, nbytes, PROT_READ | PROT_WRITE,
8 MAP_ANON | MAP_SHARED, –1, 0);
9 #elif defined(HAVE_DEV_ZERO)
10 int fd;
11 /* отображение в память файла /dev/zero */
12 if ((fd = open("/dev/zero", O_RDWR)) == –1)
13 return(MAP_FAILED);
14 shared = mmap(NULL, nbytes, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
15 close(fd);
16 #else
17 # error cannot determine what type of anonymous shared memory to use
18 #endif
19 return(shared); /* ошибка отображения в память */
20 }
Если система поддерживает флаг MAP_ANON (раздел 12.4), мы используем этот тип разделяемой памяти. В противном случае используется отображение в память файла /dev/zero (раздел 12.5).