КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Один производитель - Т потребителей
#include <stdlib.h> ttinclude <stdio,h> #include <iostream.h> #include <unistd.h> tfinclude <pthread.h> #include <errno.h> #include <semaphore,h> #include <atomic.h> const int D = 10; unsigned int T = 2; static sero_t sem; pthread_t* tid; void* writer (void* data) { unsigned long i = (int)(data); // общий размер выборки unsigned int s = 1; wnile(i-- > 0) { delay((long)rand_r(&s) * D / RAND_MAX + 1); sem_post(&sem); // объект данных произведен for(i = 0; i < Т; i++) pthread^cancel(tid[ i + 1 ]); return NULL; static char *str; // строка результирующей диагностики static volatile unsigned ind = 0; void* reader (void*) { char tid[ 8 ]; sprintf(tid, "%X", pthread_self()); unsigned int s = randO; pthread_setcanceltype(PTHREAD_CANCEL_OEFERRED, NULL); while(true) { sem_wait(&sem); // получен объект данных str[ atomic_add„value(&ind, 1) ] = *tid; pthread_testcancel(); delay((long)rand_r(&s) * D * T / RAND_MAX + 1); ) return NULL; int main(int argc, char *argv[J) { unsigned long N = 1000; int opt, val; while ((opt = getopt(argc, argv, "n:t;"))!= -1) { switch(opt) { case "n': if(sscanf(optarg, "%i", &val)!= 1) cout «"parse command line error" << endl, exit(EXIT_FAILURE); if(val > 0) N = val; break; case "t": if(sscanf(optarg, "%i", &val)!= 1) cout «"parse command line error" «endl, break; default: exit(EXIT_FAILURE); }; str = new chart N + 1 ]; tid = new pthread_t[ T + 1 ]; if(sem_init(&sem, 0, 0)) perror("semaphore init"), exit(EXIT_FAILURE); if(pthread_create(tid, NULL, writer, (void'*)N)!= EOK) perror("writer create error"), exit(EXIT_FAILURE); for(int i = 0; i < T; i++) if{ pthread_create(tid + i + 1, NULL, reader, NULL)!= EOK) perror("reader create error"), exit(EXIT.FAILURE); for(int i = 0; i < T; i++) pthread_]oin(tid[ i ],-NULL); sem_destroy(&sem); delete [] tid; str[ ind ] = '\0'; cout «str << endl; delete [] str; exit(EXIT_SUCCESS); }; Вот как выглядит результат выполнения этой программы (во избежание внесения дополнительного синхронизма в качестве общего числа циклов «производства» и числа потоков потребителей выбраны взаимно простые числа): # sy22 -n200 -t13 3456789ABCDEF7936A8547E390CB45F67A59B84037EC64F395B6AEF78B9DF34CB53B86A5FEDF 975B3A8EC46FB8A0954736FA78C3ED46F7B594EC7B83AC6F9D4BCE569A73F86BCAD74C536EB7 9F5 С 8 DA5 В463 Е FB С 7D93 7А ЕС8 5 F0E4 56В СА F690Е 7F3 85СА6 Хорошо видно, как строго последовательный поначалу порядок доступа потребителей к объектам данных десинхронизируется и становится хаотическим: каждый освободившийся потребитель приступает к работе над следующим объектом данных, как только тот становится доступен.
[1] Прим.: "point and click" – дословно "указать и выбрать мышью" – термин, означающий метод взаимодействия с интерфейсом визуальных средств разработки приложений, заключающийся в том, что для создания нового экземпляра объекта надо щёлкнуть на нём и щёлкнуть там, куда его поместить.
[2] PTHREAD_MUTEX_DEFAULT (значение по умолчанию) - попытка рекурсивного захвата мьютекса, освобождения мьютекса, захваченного дру- [3] PTHREAD_MUTEX_DEFAULT (значение по умолчанию) - попытка рекурсивного захвата мьютекса, освобождения мьютекса, захваченного дру- [4] PTHREAD_MUTEX_DEFAULT (значение по умолчанию) - попытка рекурсивного захвата мьютекса, освобождения мьютекса, захваченного другим потоком, или освобождения уже свободного мьютекса ни к чему не приводит и не возвращает ошибку выполнения.
[5] PTHREAD_MUTEX_DEFAULT (значение по умолчанию) - попытка рекурсивного захвата мьютекса, освобождения мьютекса, захваченного дру- [6] PTHREAD_MUTEX_DEFAULT (значение по умолчанию) - попытка рекурсивного захвата мьютекса, освобождения мьютекса, захваченного дру- [7] PTHREAD_MUTEX_DEFAULT (значение по умолчанию) - попытка рекурсивного захвата мьютекса, освобождения мьютекса, захваченного дру- [8] Функции SyncMutexRevive() и SyncMutexRevive_r(), из которых вторая является потокобезопасной формой первой, как это описывалось выше, отличаются между собой только способом уведомления об ошибке: первая форма возвращает -1 в случае ошибки и устанавливает errno, а вторая непосредственно возвращает код ошибки.
Дата добавления: 2014-12-10; Просмотров: 370; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |