while (!thread_done) pthread_cond_wait(&rx, &my_sync);
x++;
printf("Main thread increments X, after that X value is %d\n",x);
pthread_mutex_unlock(&my_sync);
exit(0);
}
void* compute_thread(void* dummy) {
printf("X value in thread before sleep = %d\n",x);
printf("X value in thread is incremented by 1 before sleep\n");
pthread_mutex_lock (&my_sync);
x++;
sleep(2);
printf("X value in thread after sleep = %d\n",x);
thread_done = 1;
pthread_cond_signal (&rx);
pthread_mutex_unlock (&my_sync);
return;
}
Задание на лабораторную работу:
1. Выполните следующие действия. Для каждого изменения опишите, что происходит, и дайте объяснение – почему.
a. Уберите в первом примере функцию sleep.
b. Уберите во втором примере функцию освобождения мьютекса из порожденного потока.
c. Уберите в третьем примере функцию pthread_cond_signal.
2. Решите классическую проблему «поставщик – потребитель» с использованием описанных в лабораторной работе средств синхронизации. Постановка задачи: Один поток производит данные, другой поток их потребляет. В промежуток времени между изготовлением и потреблением данные хранятся в буфере. Пример использования: Конвейер команд в Unix. Исходные данные: Данные хранятся в циклическом буфере. Циклический буфер описывается некоторой областью памяти, указателем начала данных и указателем конца данных. Поток-поставщик записывает данные в конец буфера, поток-потребитель считывает их с начала буфера. После записи или чтения соответствующим образом меняются указатели начала и конца.
Операции чтения/записи должны быть выполнены как взаимоисключающие. Если операция чтения выполняется над пустым буфером (указатель начала = указатель конца), поток-потребитель должен быть заблокирован на условной переменной до тех пор, пока поток-поставщик не запишет в буфер какие-нибудь данные. Если операция записи выполняется над полным буфером, поток-поставщик должен также быть заблокирован на условной переменной до тех пор, пока поток-потребитель не считает из буфера какие-нибудь данные. Размер буфера – 10 символов. Поток-поставщик и поток-потребитель работают в бесконечном цикле. Поток-поставщик производит по одному символу в последовательности 0,1,2...9,0,1,... и записывает его в буфер через случайный интервал времени 0,5 – 2 сек. Поток-потребитель считывает по одному символу через случайный интервал времени 0,5 – 2 сек из буфера и выводит их на экран в виде сообщений (например, Символ 0, Символ 1,...) Примерное решение: Произвести() { захватить мьютекс; if(буфер полный) ждать(буфер_неполный); произвести символ; буфер[next_in]=символ; next_in=(next_in+1)%(размер_буфера); сигнал(буфер_непустой); освободить мьютекс; ждать случайное время; } Потребить() { захватить мьютекс; if(буфер пустой) ждать(буфер_непустой); символ=буфер[next_out]; next_out=(next_out+1)%(размер_буфера); сигнал(буфер_неполный); освободить мьютекс; ждать случайное время; }
Содержание отчета по лабораторной работе:
1. Текст и результат работы программы.
2. Ответы на вопросы.
3. Вывод.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.