Вы правы, что беспокоитесь о возможности двух философов проверять мьютекс одновременно. Для правильной работы мьютекса это должно быть как-то сделано невозможным.
Если вы используете мьютексы и семафоры библиотеки C, библиотека C гарантирует, что невозможно . В частности, в этом коде:
void take_forks(int i) /* i: philosopher number, from 0 to N−1 */
{
down(&mutex); /* enter critical region */
, если два или более потоков одновременно вызывают down
на разблокированном мьютексе, down
предоставит блокировку только одному из этих потоков и немедленно возвратит для этого нить. Все остальные потоки будут «заблокированы», пока поток, который удерживает блокировку, не освободит ее, вызвав up
. Затем один из ожидающих потоков получит блокировку, down
вернется в этот поток и т. Д.
Теперь вы написали
typedef int semaphore; /* semaphores are a special kind of int */
, и это заставляет меня думать, что вы не с использованием семафоров библиотеки C, вы должны сами их реализовать. Вы должны знать, что это нельзя сделать , используя обычный C. На самом деле это невозможно сделать с помощью обычного машинного языка. Вы должны использовать специальные atomi c машинные инструкции, чтобы выполнить эту работу. Пересмотренный в 2011 году стандарт C включает специальные функции для доступа к этим инструкциям; начните с прочтения документации по stdatomi c .h .
Имейте в виду, что примитивы синхронизации сложно сделать правильно, даже для экспертов. Если вы можете написать эту программу, используя семафоры и / или мьютексы, которые кто-то уже реализовал для вас, то вы должны сделать это следующим образом.
¹ Если вы работаете с компьютером, который только один процессор - то есть он не может выполнять более одного потока одновременно - и у вас есть возможность отключать прерывания, тогда машинные инструкции atomi c не являются строго необходимыми, но лучше использовать atomi c машинные инструкции в любом случае, так что скомпилированная программа все равно будет работать, если она когда-либо будет перемещена на компьютер с более чем одним ЦП.