Студопедия

КАТЕГОРИИ:


Архитектура-(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,
exit(EXIT_FAILURE);
if(val > 0) T - val;

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; Просмотров: 348; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.007 сек.