C 使用信号灯在睡眠理发师中打印

C 使用信号灯在睡眠理发师中打印,c,multithreading,concurrency,pthreads,semaphore,C,Multithreading,Concurrency,Pthreads,Semaphore,我正在尝试使用pthreads和信号量在C中实现一个睡眠理发师问题的解决方案,唯一的部分要求是每个动作发生时都必须打印出来,例如: 理发师睡着了 顾客把理发师叫醒了 顾客在等理发师 客户离开是因为没有座位,只能在一段随机时间后返回 顾客正在理发 顾客已经离开了商店 我研究这个问题已经有一段时间了,结果是出现了各种各样的死锁,或者语句打印出了问题 这个问题的解决方案在这里并不完全适用,因为它会导致每次报表打印,例如理发师睡着后,客户叫醒理发师,或者由于上下文切换而导致报表打印混乱,这可能是一个真正

我正在尝试使用pthreads和信号量在C中实现一个睡眠理发师问题的解决方案,唯一的部分要求是每个动作发生时都必须打印出来,例如:

理发师睡着了 顾客把理发师叫醒了 顾客在等理发师 客户离开是因为没有座位,只能在一段随机时间后返回 顾客正在理发 顾客已经离开了商店 我研究这个问题已经有一段时间了,结果是出现了各种各样的死锁,或者语句打印出了问题

这个问题的解决方案在这里并不完全适用,因为它会导致每次报表打印,例如理发师睡着后,客户叫醒理发师,或者由于上下文切换而导致报表打印混乱,这可能是一个真正的问题,也可能不是一个真正的问题

我当前的解决方案是伪代码,如下所示:

int chairs       = N # available chairs
bool is_sleeping = false
bool is_cutting  = false 
bool finished    = false # All customers taken care of (Changed in main)

# Semaphores for read/write access
semaphore rw_chairs   = 1
semaphore rw_sleeping = 1
semaphore rw_cutting  = 1

semaphore barber_ready = 0 # Barber ready to cut hair
semaphore sleeping     = 0 # Barber is sleeping
semaphore cutting      = 0 # Barber cutting a customer's hair

def Barber():
   while not finished:
      wait(rw_chairs)
      wait(rw_sleeping)
      # If no chairs are being used
      if chairs == N:
         is_sleeping = true
         print("Barber is sleeping!")
         signal(rw_chairs)     # Allow others to read/write
         signal(rw_sleeping)
         wait(sleeping)        # Wait for customer to wake him up
         signal(barber_ready)  # Allow customers into the chair
         print("Barber woke up!")
      else:
         signal(rw_signal)
         chairs += 1
         signal(barber_ready)
         signal(rw_chairs)
      # If the barber isn't done for the day, help the customer
      if not finished:
         print("Helping a customer")
         # Wait a random amount of time
         print("Finished helping a customer")
         signal(cutting) # Let the customer leave after the hair cut
      else:
         print("Barber is done for the day!")

def Customer():
   bool helped = false
   while not helped:
      wait(rw_chairs)
      wait(rw_cutting)
      if chairs == N and not is_cutting: # If the barber is free
         wait(rw_sleeping)
         if is_sleeping:
            signal(sleeping) # Wake the barber up
            is_sleeping = false
            print("Customer has woken the barber up")
         signal(rw_sleeping)
         is_cutting = true
         signal(rw_chairs)
         signal(rw_cutting)
         wait(barber_ready) # Wait for the barber to be ready
         wait(cutting)      # Wait for him to finish cutting hair
         print("Customer has had his hair cut")
         helped = true
      else if chairs > 0:
         chairs -= 1
         print("Customer is waiting in a chair")
         signal(rw_chairs)
         signal(rw_cutting)
         wait(barber_ready)
         wait(cutting)
         print("Customer has had his hair cut")
         helped = true
      else:
         signal(rw_chairs)
         signal(rw_office)
         print("All chairs taken, will return later")
         # Wait a random amount of time 
   print("Customer is leaving the barbershop")
如果没有死锁,使用3把椅子,我会得到以下输出:

Barber has fallen asleep
Customer is waiting in a chair
Customer is waiting in a chair
Customer is waiting in a chair
All chairs used, will return later
All chairs used, will return later
... (repeat the above line infinitely)
我很清楚,理发师没有适当地让顾客进来——但即使这样,我觉得我的结构完全错了。我认为我处理这个问题的方法是错误的,而且可能使它过于复杂

如果这里有人对如何构建一个有效的解决方案有任何建议,或者对我当前的解决方案有任何建议,我将不胜感激。或者如果我在正确的轨道上,可能是朝着正确的方向推动


谢谢

我设法让它工作起来了

鉴于我以前在这里的任何地方都没有看到过这样的问题,我会回答我自己的问题,以防其他人遇到像我这样寻求帮助的问题

我最初的方法并不是完全错误的,但是有一些小的调整需要让它正常工作。我没有使用6个信号量,而是使用了5:2控制读/写访问,3控制排队/睡眠

伪代码如下所示:

# Constants
SLEEPING = 0
AWAKE    = 1
BUSY     = 2

# Read/Write semaphores
Semaphore rw_chairs = 1      # Access to chairs
Semaphore rw_status = 1      # Access to barber status

# Access semaphores
Semaphore waiting   = 0      # Line for waiting customers
Semaphore cutting   = 0      # Semaphore to hold customer while getting hair cut
Semaphore sleeping  = 0      # Semaphore for barber to sleep

int   chairs        = n      # Available chairs to sit in
int   status        = AWAKE  # Barber Status (could also be a boolean for sleeping)
bool  finished      = false  # Is the program finished

def Barber():
   while not finished:
      wait(rw_chairs)
      wait(rw_status)
      # If there is nobody waiting and the barber isn't asleep
      if chairs == n and status != SLEEPING:
         barber = SLEEPING;
         print("Barber went to sleep!")
         signal(rw_status)
         signal(rw_chairs)
         wait(sleeping)    # Go to sleep
         print("Barber woke up!")
         signal(waiting)   # Let the next customer in
      else:
         signal(waiting)   # Let the next customer in
         chairs += 1       # Free the chair they sat in
         barber = BUSY     # Set the barber to busy
         signal(rw_status)
         signal(rw_chairs)

      # Once it gets here, the barber is awake and must help someone
      if not finished:
         print("Barber is cutting a customer's hair")
         # Cut the customer's hair
         print("Barber finished cutting the customer's hair")
         signal(cutting) # Release the customer so they can leave

    # barber's finally done
    print("Barber finished work for the day");

def Customer():
    bool helped = false

    print("Customer arrived at the Barber Shop!")
    while not helped:
       wait(rw_chairs)
       wait(rw_status)
       if chairs == n and status == SLEEPING:
          status = AWAKE
          print("Customer woke up the barber")
          signal(rw_status)
          signal(sleeping)  # Wake up the barber
          wait(waiting)     # Be the next customer to get helped (happens immediately)
          signal(rw_chairs)

          helped = true; // This customer is being helped
       else:
          signal(rw_status)
          if chairs > 0:
             chairs -= 1  # Claim a chair
             signal(rw_chairs)
             print("Customer sitting in a chair")
             wait(waiting) # Wait for the barber

             helped = true; // This customer is being helped
          else:
             print("Barber Shop is busy, will return later")
             signal(rw_chairs)
             # Wait a while before returning
       # If the customer is being helped
       if helped:
          print("Customer is getting a hair cut")
          wait(cutting)
          print("Customer is finished getting a haircut")
大体上,一旦所有客户线程都加入,它就会将finished设置为true,并唤醒可能正在睡觉的理发师以完成程序

通过这种方法,理发师和顾客都会先读取椅子,然后读取状态,然后按相反的顺序释放,以防止循环等待造成死锁