ВУЗ:
Составители:
9
обозначения, поскольку тем, кто не знает датского языка, эти обозначения ничего не
говорят (да и тем, кто знает язык, говорят немного). Впервые обозначения down и up
появились в языке Algol 68.
Как показано в листинге 2, проблему потерянных сигналов запуска можно
решить с помощью семафоров. Очень важно, чтобы они были реализованы
неделимым образом. Стандартным способом является реализация операций down и
up в виде системных запросов, с запретом операционной системой всех прерываний
на период проверки семафора, изменения его значения и возможного перевода
процесса в состояние ожидания. Поскольку для выполнения всех этих действий
требуется всего лишь несколько команд процессора, запрет прерываний не приносит
никакого вреда. Если используются несколько процессоров, каждый семафор
необходимо защитить переменной блокировки с использованием команды TSL,
чтобы гарантировать одновременное обращение к семафору только одного
процессора. Необходимо понимать, что использование команды TSL
принципиально отличается от активного ожидания, при котором производитель или
потребитель ждут наполнения или опустошения буфера. Операция с семафором
займет несколько микросекунд, тогда как активное ожидание может затянуться на
существенно больший промежуток времени.
#define N 100 /* количество сегментов в буфере */
typedef int semaphore; /* семафоры - особый вид целочисленных переменных */
semaphore mutex = 1; /* контроль доступа в критическую область */
semaphore empty = N; /* число пустых сегментов буфера */
semaphore full = 0; /* число полных сегментов буфера */
void producer(void)
{
int item;
while (TRUE) { /* TRUE - константа, равная 1*/
item = produce_item(); /* создать данные, помещаемые в буфер */
down(&empty); /* уменьшить счетчик пустых сегментов буфера */
down(&mutex); /* вход в критическую область */
insert_item(item); /* поместить в буфер новый элемент */
up(&mutex); /* выход из критической области */
up(&full); /* увеличить счетчик полных сегментов буфера */
}
}
void consumer(void)
{
int item;
while (TRUE) { /* бесконечный цикл */
down(&full); /* уменьшить числа полных сегментов буфера */
down(&mutex); /* вход в критическую область */
item = remove_item(); /* удалить элемент из буфера */
up(&mutex); /* выход из критической области */
up(&empty); /* увеличить счетчик пустых сегментов буфера */
consume_item(item); /* обработка элемента */
}
}
Листинг 2 – Проблема производителя и потребителя с семафорами
обозначения, поскольку тем, кто не знает датского языка, эти обозначения ничего не
говорят (да и тем, кто знает язык, говорят немного). Впервые обозначения down и up
появились в языке Algol 68.
Как показано в листинге 2, проблему потерянных сигналов запуска можно
решить с помощью семафоров. Очень важно, чтобы они были реализованы
неделимым образом. Стандартным способом является реализация операций down и
up в виде системных запросов, с запретом операционной системой всех прерываний
на период проверки семафора, изменения его значения и возможного перевода
процесса в состояние ожидания. Поскольку для выполнения всех этих действий
требуется всего лишь несколько команд процессора, запрет прерываний не приносит
никакого вреда. Если используются несколько процессоров, каждый семафор
необходимо защитить переменной блокировки с использованием команды TSL,
чтобы гарантировать одновременное обращение к семафору только одного
процессора. Необходимо понимать, что использование команды TSL
принципиально отличается от активного ожидания, при котором производитель или
потребитель ждут наполнения или опустошения буфера. Операция с семафором
займет несколько микросекунд, тогда как активное ожидание может затянуться на
существенно больший промежуток времени.
#define N 100 /* количество сегментов в буфере */
typedef int semaphore; /* семафоры - особый вид целочисленных переменных */
semaphore mutex = 1; /* контроль доступа в критическую область */
semaphore empty = N; /* число пустых сегментов буфера */
semaphore full = 0; /* число полных сегментов буфера */
void producer(void)
{
int item;
while (TRUE) { /* TRUE - константа, равная 1*/
item = produce_item(); /* создать данные, помещаемые в буфер */
down(&empty); /* уменьшить счетчик пустых сегментов буфера */
down(&mutex); /* вход в критическую область */
insert_item(item); /* поместить в буфер новый элемент */
up(&mutex); /* выход из критической области */
up(&full); /* увеличить счетчик полных сегментов буфера */
}
}
void consumer(void)
{
int item;
while (TRUE) { /* бесконечный цикл */
down(&full); /* уменьшить числа полных сегментов буфера */
down(&mutex); /* вход в критическую область */
item = remove_item(); /* удалить элемент из буфера */
up(&mutex); /* выход из критической области */
up(&empty); /* увеличить счетчик пустых сегментов буфера */
consume_item(item); /* обработка элемента */
}
}
Листинг 2 – Проблема производителя и потребителя с семафорами
9
Страницы
- « первая
- ‹ предыдущая
- …
- 7
- 8
- 9
- 10
- 11
- …
- следующая ›
- последняя »
