Sleeping Barber Problem and AI Self-Driving Cars


By Lance Eliot, the AI Trends Insider

The sleeping barber problem. It’s a classic. If you are unfamiliar with it, you might be thinking that I’ve somehow got a barber that falls asleep when I come in to get my haircut. That would indeed be a problem. Just imagine the kind of haircut I might get if the barber kept falling asleep during the haircut. It would take a long time to get my haircut done, and it might look like it was done in a series of staggered steps. Fortunately, that’s not the sleeping barber problem that I’m referring to.

Well known among computer scientists and especially those that study real-time systems, the sleeping barber problem dates back to the mid-1960s when famous computing enthusiast Edsger W. Dijkstra (known generally be his initials of EWD), depicted the problem for purposes of exploring how to handle various concurrent programming related issues. If you aren’t aware of EWD’s body of work, his efforts were of a pioneering nature and we all today utilize daily in our computer efforts the insights that he gleaned.

I met EWD a few times at industry events, and true to his reputation he was a bit gruff and had little patience for those that weren’t up-to-par. He had made a choice via advice from a mentor to earlier in his career switch from his focus on physics to instead focus on providing rigor to what at the time was a Wild West of computer programming. Thankfully he made the switch. He was also well known for a disdain for the phrase “computer science” and instead insisted that if this emerging field of study was going to be named that at least it be called “computing science” (you might have heard his famous line, namely that computer science is no more about computers than is astronomy about telescopes).

Let’s take a look at the sleeping barber problem.

Imagine that there’s a barber willing to cut people’s hair. The barber cuts only one person’s hair at a time. There is one barber’s chair. Once the barber starts to cut someone’s hair, the barber sees it to the end of the haircutting for that person. The barber never directly turns away someone that wants a haircut if the barber is available to cut someone’s hair.

If the barber believes that there is no one desiring a haircut, the barber will go to sleep, doing so in the barber’s chair. If someone arrives at the barber’s door and wants a haircut and the barber is asleep, the barber has a sixth sense and will awaken in order to cut that person’s hair. When the barber first arrives to open the barbershop, the barber opens up the shop and sits in the barber chair and falls asleep, ostensibly to await for a customer that wants a haircut.

As an aside, yes, I realize that this barber might end-up getting a lot of sleep during a workday, but hey, that’s fine and don’t we all need naps during our workdays?

From time-to-time, people will arrive in an effort to get their haircut undertaken. There’s just the one barber (we can complicate things with more than one barber, but the foundational problem is sufficient to concentrate on just having one barber). There is a waiting room into which the people desiring a haircut will ultimately wait, if a wait is needed and possible. In the waiting room, there is some limited number of seats, which I’ll go ahead and call N.

The barber’s chair and where the haircutting is taking place is apart from the area where the waiting room is. I mention this because it’s a significant element to the nature of the problem. Many might assume that the waiting area and the haircutting area are all in the same physical space, such that those sitting waiting can watch the haircutting, and the barber can watch those that are waiting for a haircut. We’re not going to have this kind of a setup in the case of the sleeping barber problem. Instead, consider that the haircutting room is disjointed from the waiting room and that you can’t see either one from the other one. I know this seems odd in comparison to most actual barbershops, but hey, go with me on this assumption, thanks.

By the way, there are lots of online videos that try to explain the sleeping barber problem. Please be aware that many of them, even the most popular ones, either do a lousy job of explaining the problem, or fail to explain the solution, or explain the solution in a lopsided manner. I am hoping that my explanation herein will be better than those attempts by others. When I used to describe the problem and solution as a professor, I did my best to make clear cut to the students what the problem is and what the solutions consist of.

I’ll say one other thing. For computer practitioners, they often glaze over in the eyes when I start to describe the sleeping barber problem. I don’t blame them. There are various at times obscure “problems” in the computer science field and would rarely apply to the everyday efforts of a typical computer programmer or software engineer. In this case, though, I assure you that the sleeping barber problem has real-world practical implications and it’s worthwhile to know about it. Really, I swear to you that’s the case.

Okay, back to the problem description. One barber. Willing to cut hair. People come to get their haircut. These prospective customers will first go to the haircutting room to see if the barber is available. They’ll know the barber is available because the barber will be sleeping when otherwise not cutting hair. If the barber is cutting hair when the prospective customer comes to look and see if the barber is available, the customer will then mosey on over to the waiting room, which takes a bit of time to wander over to (recall that the haircutting room and the waiting room are apart from each other).

A prospective customer that has seen that the barber is cutting hair and therefore busy, once that prospective customer gets to the waiting room they will try to sit down in an available seat. If all of the seats are taken, the prospective customer leaves. They might or might not return at some later point in time, which for purposes of the problem we don’t care per se whether a “spurned” prospective customer opts to return later or not.

I suppose you could say that the barber ought to incentivize someone to come back to get a haircut if the person was unable to wait in the waiting room. Sure, that would be handy if this were more of a business-oriented problem rather than a computer science problem. We’ll stay with the computer science focus for the moment.

You might be wondering how the people in the waiting room are going to become aware when the barber is available to cut their hair. The barber upon finishing cutting of someone’s hair will proceed over to the waiting room to see if someone is waiting. If there is someone waiting, the barber then brings them over into the haircutting room and proceeds to cut their hair. If there is no on sitting in the waiting room, the barber will simply return to the haircutting room and fall asleep in the barber’s chair.

The barber cuts hair in some amount of time T, which can vary depending upon the nature of the haircut. A haircut cannot somehow be done instantaneously, such that there is no such thing as T=0. We don’t know how much time T it takes for any given haircut and will just assume that it is some quantifiable amount of time, and for which too it is a bounded amount of time. In essence, T cannot be equal to infinite (i.e., haircuts are guaranteed to eventually be completed).

For those prospective customers that end-up in the waiting room, they are willing to wait as long as it takes to get a haircut. We could complicate matters by saying that they only will wait some limited amount of time, but for the foundational aspects we’ll leave it that they’ll just wait. Heck, maybe the barber has really good WiFi and so the waiting customers can use their smartphones and do streaming of their favorite shows.

I’ve provided so far the essence of the setup. I added a few elaborations and maybe a little humor to the description but figured it might make it less painful for your purposes of getting to know the key setup aspects.

Let’s walk through some examples.

The barber shows-up at 7 a.m. and dutifully opens the barbershop, which includes opening the waiting room and opening the haircutting room. There are no prospective customers as yet. The barber goes into the haircutting room, sits in the barber’s chair, and promptly goes to sleep. It could be that the barber already had a solid night’s sleep and so really doesn’t need more sleep, or it could be that the barber partied last night and hasn’t gotten any sleep at all, having arrived at 7 a.m. from the bars and nightclubs, in any case, there’s no customers and so the barber sleeps.

Let’s next pretend that a prospective customer shows up. The prospective customer goes directly to the haircutting room, not yet having seen or been to the waiting room and looks in the haircutting room to see if the barber is available.

Since in this instance the barber is sleeping, it implies the barber is available. The barber via a sixth sense wakes-up and happily cuts the hair of this first customer. When the haircut is completed, the customer leaves and the barber goes back to sleep. The barber cut the hair of one person. There were no other people that arrived. There was no one in the waiting room.

Ka-ching, the barber just made some money (well, I admit that I never said whether the barber gets paid to do haircuts, and so maybe the barber does this for free; just wanted to see if you were paying attention as to what I might have left out, but we don’t care herein whether the barber is getting paid or not).

Second Customer Arrives

Another prospective customer arrives, goes to see if the barber is available, sees the barber sleeping, the barber awakens, and starts to cut the hair of this customer. During the haircut, another prospective customer arrives, and goes to the door of the haircutting room. Upon seeing the barber busily cutting hair, the customer then makes their way over to the waiting room. In this case, let’s say there are 2 seats in the waiting room (thus, N=2). The prospective customer notices that both seats are empty and so opts to sit down in one of the seats. They now preoccupy themselves in whatever manner so desired and are waiting to get their haircut.

Upon completing the haircut that was underway, the barber says goodbye to the customer that quite enjoyed getting the haircut, and the barber then meanders over to the waiting room. Maybe the barber secretly hopes there’s no one there, such that sleep would be possible. Or, maybe the barber is eager to work and is hoping that there’s someone in the waiting room.

In this case, there is someone waiting in the waiting room. The barber brings along the waiting customer and takes the customer over into the haircutting room. The barber proceeds to cut their hair. While doing so, another prospective customer shows up, looks and sees that the barber is busy, goes over to the waiting room, sees the two available seats, and takes a seat. Furthermore, another prospective customer comes along, sees that the barber is busy, so goes to the waiting room and grabs the second seat. All seats in the waiting room are now full, for the moment.

This haircut is taking a while to do. Turns out another prospective customer comes along, sees that the barber is cutting hair, so goes over to the waiting room. Darn, all of the seats are taken by other waiting customers. Guess today was the wrong day to want a haircut. This now despondent prospective customer walks away, unhappy and wishing they had come sooner to get their haircut.

I think that’s enough of an example to now reveal the problem at-hand.

The setup seems just fine. Putting aide the tidbits about possibly losing customers because of the limited wait room, let’s focus on something else instead.

Sometimes when the problem itself is revealed, it seems almost like a cheat in that if the problem had been described in a different way that you might have already detected the potential problem. In this case, I gave some clues but not much. Sorry.

The problem has to do with time.

We have the time it takes to do a haircut. There’s also an unstated amount of time for the barber to walk over to the waiting room to see if there’s anyone in there. There’s more unstated time, such as the time it takes for a prospective customer to walk over to the waiting room once they have seen that the barber is busy.

Remember that it was mentioned that the haircutting room and the waiting room are apart from each other, and that you cannot see the room from the other room. Let’s also go with the idea that the path from the haircutting room to the waiting room can be convoluted and such that someone on that path does not see anyone else on that path, even if there is someone else on the path.

This then is the problem.

A prospective customer arrives and let’s say sees that the barber is busy, and so wanders over to the waiting room, which will take some amount of time, Z. Suppose the barber finishes the haircut just moments after that prospective customer has proceeded toward the waiting room, and meanwhile the barber has a faster way to get to the waiting room and so zooms over to see if there is anyone waiting. At that moment in time, there isn’t anyone in the waiting room, even though we know that there’s someone on their way to it. The barber though sees that the waiting room is empty, and so goes back to the haircutting room and will promptly go to sleep because there aren’t any customers (as far as the barber knows).

The prospective customer finally arrives at the waiting room. They sit down. They are unaware that the barber came over to check and see whether anyone was there. This prospective customer assumes that the barber is still cutting the hair of the person that they saw when having come to the haircutting room door. We’ve said that the prospective customer is willing to wait until the barber becomes free, which will only be known when the barber comes to the waiting room.

But, we now have a conundrum.

The barber is sleeping and doesn’t believe that there is anyone in the waiting room. The prospective customer that is patiently sitting in the waiting room is willing to just sit there, happily awaiting the presumed arrival at some point in time of the barber to then proceed with getting a haircut. Neither one realizes that they are both now waiting. You might say this is like waiting for Godot (a literary joke, if I might!). They will both presumably wait until forever, or maybe once the cows come home.

There are other variants on the problem, all of which involve time.

In the computing field, there are circumstances wherein you might have one process, in this sleeping barber case embodied in the notion of the barber, and you might have another process, in this case embodied in the customer that’s waiting for the barber, whereby the two processes get themselves into a similar mess. Each might be waiting on the other, not realizing that they are indeed waiting on each other.

Suppose my PC tries to connect with my printer. The printer is momentarily busy because it is in the midst of printing a document. The PC upon inquiring of the printer is told by the printer that it is busy and so if the PC wants to send another document to the printer, the PC will need to wait until the printer is finished printing the being printed document. The PC is a bit slow and while it is digesting the aspect that the printer is busy, the printer actually finishes printing and tries to let the PC know. The PC though has finally gotten squared away that the printer is busy and so subsequently is going to wait until the printer says it is not busy.

You could end-up in a situation wherein the PC believes it is waiting for the printer, and the printer believes it is waiting for the PC. The document that you wanted to get printed is now in limbo, due to the aspect that these two processes got themselves out-of-synch and are doing a lousy job of inter-process communication.

At the heart of any solid operating system is the ability to cope with synchronization among multiple processes and trying to ensure that there is proper inter-process communications taking place. If an OS doesn’t’ have its act together on dealing with this, you are going to have all sorts of problems ensue related to the running of processes.

What does this have to do with AI self-driving cars?

At the Cybernetic AI Self-Driving Car Institute, we are developing AI software for self-driving cars. As such, one of the crucial elements for any self-driving car involves the proper design and development of the AI so that the multitude of processes and the appropriate synchronization and inter-process communication occurs, all of which has to happen in real-time and in the right manner.

Sleeping Barber Problem Best Not Happen with AI Self-Driving Cars

In that sense, there’s a chance that a poorly designed or insufficiently-developed AI self-driving car could find itself mired in the sleeping barber problem. Shouldn’t happen. Better not happen. Lives could depend upon it not happening.

There are some key overall tasks that occur by the AI to undertake the driving task, which includes:

  •         Sensor data collection and interpretation
  •         Sensor fusion
  •         Virtual world model updating
  •         AI action planning
  •         Car controls command issuance

For more about the key AI driving tasks, see my framework:

For aspects of the levels of AI self-driving cars, see my article:

For the timing aspects of the AI, see my article:

For the freezing robot problem and AI self-driving cars, see my article:

Suppose that we have an AI self-driving car that’s considered to be at Level 5. A Level 5 self-driving car is one that is driven entirely by the AI and there is no need and no provision for a human driver. In fact, a Level 5 self-driving car will usually lack a brake pedal, nor have a gas pedal, nor a steering wheel, since those are contraptions only needed for a human driver. AI self-driving cars that are less than a Level 5 are considered being co-driven by a human driver and the AI, and therefore will have the usual mechanisms needed for a human driver to participate in the driving task. This co-sharing of the driving task raises some serious and disconcerting potential problems.

For my article about the issues underlying co-sharing of the driving task, see:

Imagine a Level 5 self-driving car that is driving along on a highway. It’s nighttime. The AI is using its sensors to try and detect the surroundings of the self-driving car. Using the cameras, the radar, the LIDAR, the sonic sensors, the AI is receiving data about what the sensors are detecting. Because it is nighttime, the road ahead is somewhat obscured by darkness, thus the cameras aren’t as readily able to visually detect the scene ahead as if it were daylight. The radar becomes perhaps especially important in this setting.

At a speed of say 50 miles per hour, the self-driving car is moving along at a clip of about 75 feet per second. If the AI determines that there is a pedestrian up ahead and in the path of the self-driving car, it will need time to issue commands to the car controls, such as braking the car, and then it will take time for the car to actually come to a stop once the braking operation is enacted.

Let’s assume that the AI checks with the sensor detection process and requests whether there is a pedestrian up ahead (at least as can be detected within the distance limitations of the sensors and the circumstances of the in-motion car). It could be that the sensor detection process indicates there isn’t a pedestrian up ahead.

The AI opts to proceed with other driving tasks and for the moment believes that there is not a pedestrian up ahead.

Meanwhile, the sensor detection process receives a new set of data coming from the sensors, and upon analysis determines there now might be a pedestrian up ahead. It could be that a moment ago, the sensor data had been too sketchy and there was noise in it, so determining that a pedestrian was present was not readily feasible, a moment ago. Or, it could be that the self-driving car has moved forward at the 75 feet per second and it now has gotten closer to a pedestrian that was there in the street before but was outside the range of the sensors, a moment ago. Or, it could be that the pedestrian was not in the street before, but in the moment since the last sensor data collection, the pedestrian has rushed into the street and now is in front of the approaching AI self-driving car.

Here’s your worst fears. The AI overarching process is still operating under the indication there isn’t a pedestrian up ahead. The sensor detection process now believes that a pedestrian is up ahead. Suppose that the AI overarching process was designed so that it will assume there isn’t a pedestrian until the sensor detection process alerts the AI overarching routine that there is one there. Suppose the sensor detection process was designed so that it waits until the AI overarching process asks about pedestrian detections.

You could now have one process that’s waiting on the other, but the other one doesn’t realize it is being waited upon.

By the time that the AI overarching process checks in with the sensor detection process, it might now be too late. Even if the AI overarching process now realizes that it is crucial to brake the self-driving car, the amount of time needed to issue the car controls commands and have the car respond, well, it could be that the pedestrian is going to get hit.

In case you think that something like this would certainly never happen, you might want to take a look at the Uber AI self-driving car incident that occurred in Arizona and involved the self-driving car hitting and killing a pedestrian. We don’t yet know the inner workings of what actually happened, since it hasn’t been made public, but something like this timing matter might have been involved. It could be a variant of the sleeping barber problem.

For my article analyzing the Uber incident, see:

For the later indication that many of my key points were indeed prescient, see:

Let’s now return to the sleeping barber problem.

You might be wondering what kind of solutions there are for the sleeping barber problem.

The solution that is one of the most commonly used approaches involves making use of two techniques in combination with each other. One technique involves the use semaphores, which are essentially flags to indicate some kind of status, and the other technique used in combination with semaphores is usually mutual exclusion (often abbreviated as “mutex”).

Mutual exclusion consists of a process that can claim exclusive control over something and any other process is prevented from trying to control that something (during that time period of exclusivity). We might therefore setup a semaphore that indicates the status of the waiting room, and have the barber momentarily acquire control over that status when it wants to check and see if there are any customers in the waiting room. This same semaphore could be used by a prospective customer that is able to gain control over it, momentarily, and check the status.

Without getting too deep into the details, this approach typically requires three semaphores, including one that is a count of the number of customers in the waiting room, another is whether the barber is cutting hair or not, and the third is used for the mutex status. If you are interested in the various solutions and sample source code, you can readily find online the code in numerous programming languages, including Python, Java, C++, and so on.

The addition of mutual exclusion requires that the processes each have a specific portion that deals with the mutual exclusion activity. This code segment is often referred to as a critical section. The critical section is usually supposed to be very short and quick to operate. When the overall process is doing its thing, considered its overall non-critical section, and wants to involve the mutex, it needs to make a request to do so, and goes into a waiting mode until granted the mutex control, and once it has completed the mutex activity it is expected to then release the control.

There are various potential problems associated with the mutual exclusion solution. One is that the waiting time for the mutex control might be inordinately long, while another concern is that whomever gets the mutex control might fail to release it. Each of these can create various forms of deadlock and potentially starvation. There are other solutions associated with dealing with these matters.

For AI developers that have developed real-time systems for say robots, they likely have had to deal with these kinds of sleeping barber problems, and therefore are familiar with how to develop their systems accordingly. On the other hand, for AI developers that have not done much work on real-time systems, they are often unfamiliar with these kinds of issues.

I mention this because the auto makers and tech firms are using a variety of AI developers, some that are familiar with these kinds of real-time issues and others that are no quite so familiar with it. Indeed, there are some AI developers that just assume that the underlying operating system will take care of any of these kinds of process synchronization and inter-process communications aspects. That can be a faulty assumption.

An AI self-driving car is a real-time system that needs to operate with often dozens of core processes occurring concurrently, possibly even hundreds of processes and thousands of mini-processes overall occurring simultaneously, and there needs to be an appropriate design and coding for their synchronization and inter-process communication.

The complexity of the AI for a self-driving car can become so thorny that it’s difficult to know for sure that there aren’t potential sleeping barbers hidden within the system. If a crucial “barber” gets confused or is not timely updated, the action of the self-driving car can become quite untoward. Life or death of humans can depend on how well the barber sleeping problem has been solved for an AI self-driving car.

Copyright 2018 Dr. Lance Eliot

This content is originally posted on AI Trends.