一种避免死锁的方法是让 1 号哲学家在拿起他的筷子之前等待一段时间。就代码而言,可让他在拿起自己的筷子之前休眠指定的一段时间 (sleep_seconds)。如果他休眠的时间足够长,该程序就可能会完成而不发生任何实际死锁。可以将他休眠的秒数指定为可执行程序的参数。如果不指定参数,该哲学家就不会休眠。
以下伪代码显示了每位哲学家的逻辑:
while (there is still food on the table) { if (sleep argument is specified and I am philosopher #1) { sleep specified amount of time } grab right chopstick grab left chopstick eat some food put down left chopstick put down right chopstick }
下面列出了该程序的一次运行,在这次运行中 1 号哲学家在拿起他的筷子之前等待 30 秒。该程序运行至完成,所有五位哲学家都吃到了面条。
% a.out 30 Philosopher 0 is done thinking and now ready to eat. Philosopher 0: got right chopstick 0 Philosopher 0: got left chopstick 1 Philosopher 4 is done thinking and now ready to eat. Philosopher 4: got right chopstick 4 Philosopher 3 is done thinking and now ready to eat. Philosopher 3: got right chopstick 3 Philosopher 0: eating. Philosopher 2 is done thinking and now ready to eat. Philosopher 2: got right chopstick 2 Philosopher 1 is done thinking and now ready to eat. Philosopher 0: got right chopstick 0 Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 0: got right chopstick 0 Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 0: got right chopstick 0 Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 0: got right chopstick 0 Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 0: got right chopstick 0 Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 0: got right chopstick 0 Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 0: got right chopstick 0 Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 0: got right chopstick 0 Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 0: got right chopstick 0 Philosopher 0: got left chopstick 1 Philosopher 0: eating. ... Philosopher 0: got right chopstick 0 Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 0: got right chopstick 0 Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 0: got right chopstick 0 Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 0: got right chopstick 0 Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 0: got right chopstick 0 Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 0: got right chopstick 0 Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 0: got right chopstick 0 Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 0: got right chopstick 0 Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 0 is done eating. Philosopher 4: got left chopstick 0 Philosopher 4: eating. Philosopher 4 is done eating. Philosopher 3: got left chopstick 4 Philosopher 3: eating. Philosopher 3 is done eating. Philosopher 2: got left chopstick 3 Philosopher 2: eating. Philosopher 2 is done eating. Philosopher 1: got right chopstick 1 Philosopher 1: got left chopstick 2 Philosopher 1: eating. Philosopher 1 is done eating. % Execution terminated normally
尝试多次运行该程序,并指定不同的休眠参数。如果 1 号哲学家在拿起他的筷子之前仅等待很短的一段时间,那么发生什么情况呢?如果他等待的时间更长一些,又会怎么样?尝试为可执行程序 a.out 指定不同的休眠参数。在使用或不使用休眠参数的情况下多次重新运行该程序。该程序有时会挂起,而有时又可以运行至完成。程序是否挂起取决于线程的调度情况以及线程进行锁请求的时间。