Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7735881
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 1, 20262026-06-01T07:36:39+00:00 2026-06-01T07:36:39+00:00

I wanted someone to resolve my confusion on this topic. It may sound simple,

  • 0

I wanted someone to resolve my confusion on this topic. It may sound simple, but am really confused.

In producer/consumer problem, I used 4-semaphore solution. I used a different lock for each of the critical sections.
Say,

Pseudo code of producer:
    wait(slot) // counting sem
       wait(mutex1) // binary sem
         rear <-- rear + 1
         buffer[rear] <-- item
       signal (mutex1)
    signal(items)

Where I use, “mutex2” as a second Mutex for my consumer, as “mutex1” in producer.

Now, my question is. If my producer and consumer is not using a buffer (rear and front) but using a stack, where only they can manipulate [top]. Do I need to use one mutex or two different locks as in my 4-semaphore, in order to ensure mutual exclusion.

 Pseudo code of consumer with stack:
         wait (message)
            wait (mutex)
              getspace <-- stack[top]
              top – 1
            signal (mutex)
          signal (slot)

Personally, I think I need one lock for both procedures, so I make sure none of the producer and consumer access the top concurrently. But am not sure about that.
Thank you.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-01T07:36:41+00:00Added an answer on June 1, 2026 at 7:36 am

    I’m not 100% sure that I follow your pseudo-code but I’ll do my best to explain how to use semaphores to manage a stack from within the Producer-consumer process.

    When you have a stack that is being accessed across multiple threads, you will need to lock it when the data is being accessed or, more specifically, when it is being pushed and popped. (This is always an underlying assumption of the Producer-consumer problem.)

    We start off by defining a mutex that we will use to lock the stack.

    Global Declaration of Process Semaphores

    stackAccessMutex = semaphore(1) # The "(1)" is the count 
                                    # initializer for the semaphore.
    

    Next, we will need to lock it when we are adding or removing data from it in our Consumer and Producer threads.

    Producer thread

    dataPushBuff #Buffer containing data to be pushed to the stack.
    
    …dataPushBuff is assigned…
    
    stackAccessMutex.wait()
        stack.push(dataPushBuff)
    stackAccessMutex.signal()
    

    Consumer thread

    dataRecvBuff = nil # Defining a variable to store the pushed
                       # content, accessible from only within 
                       # the Consumer thread.
    
    stackAccessMutex.wait()
        dataRecvBuff = stack.pop()
    stackAccessMutex.signal()
    
    …Consume dataRecvBuff as needed since it's removed from the stack…
    

    So far, everything is pretty straight forward. The Producer will lock the stack only when it needs to. The same is true for the consumer. We shouldn’t need another semaphore, should we? Correct? No, wrong!

    The above scenario makes one fatal assumption– that the stack will always be initialized with data before it is popped. If the consumer thread executes before the producer thread gets a chance to pop any data, you will generate an error within your consumer thread because stack.pop() will not return anything! To fix this, we need to signal the consumer that data is available in the stack.

    First, we need to define a semaphore that can be used to signal whether data in the stack exists or not.

    Global Declaration of Process Semaphores, Version #2

    stackAccessMutex = semaphore(1)
    itemsInStack     = semaphore(0)
    

    We initialize our itemsInStack to the number of items in our stack, which is 0 (see 1).

    Next, we need to implement our new semaphore into our Producer and Consumer threads. First, we need to have the Producer signal that an item has been added. Let’s update the Producer now.

    Producer thread, Version #2

    dataPushBuff
    
    …dataPushBuff is assigned…
    
    stackAccessMutex.wait()
        stack.push(dataPushBuff)
    stackAccessMutex.signal()
    itemInStack.signal() #Signal the Consumer, we have data in the stack!
                         #Note, this call can be placed within the 
                         #stackAccessMutex locking block, but it doesn't 
                         #have to be there.  As a matter of convention, any
                         #code that can be executed outside of a lock, 
                         #should be executed outside of the lock.
    

    Now that we can check to see if there is data in the stack via a semaphore, let’s re-write our Consumer thread.

    Consumer thread, Version #2

    dataRecvBuff = nil # Defining a variable to store the pushed
                       # content, accessible from only within 
                       # the Consumer thread.
    
    itemsInStack.wait()
    stackAccessMutex.wait()
        dataRecvBuff = stack.pop()
    stackAccessMutex.signal()
    
    …Consume dataRecvBuff as needed since it's removed from the stack…
    

    … and that’s it. As you can see, there are two semaphores and both are mandatory (see 2) because we need to lock our stack when it’s accessed and we need to signal our consumer when data is available and lock it when there is nothing in the stack.

    Hope that answered your question. I’ll update my response if you have any specific questions.

    1. Theoretically, when the process starts, you could
      pre-initialize your stack with data. In this case, you can should
      initialize your itemsInStack semaphore with the value that is
      equal to the stack count. However, in the case of this example, we
      are assuming that there is no data in the stack, nor none to
      initialize.

    2. It is worth mentioning that under one, specific circumstance you
      can theoretically get away with using just the stackAccessMutex.
      Consider the case where the stack always contains data. If the
      stack is infinite, we do not need to signal our Consumer that data
      has been added because there always will be data. However, in
      reality an “infinite stack” doesn’t exist. Even if that should be
      the case within your current context, there’s no overhead in adding
      the safety net of the itemsInStack semaphore.

      Also, it may be tempting to to throw out the itemsInStack counting
      semaphore if under your current circumstance a call to
      stack.pop() would not cause any error if it were to not return any
      data on an empty stack.

      This is plausible, but not recommended. Assuming the Consumer thread is executing the
      code on a loop, the loop will continuously execute the stack consumption code while
      there is no data to consume. By using the itemsInStack semaphore, you are pausing the
      thread until data arrives which should save a few CPU cycles.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I don't like this code but I always get confused with threads so wanted
Can someone teach me or give me a link for my problem? I wanted
I just wanted someone to check this cron code for me, and let me
I most likely suspect is not possible but I wanted to know If someone
I've seen a few other threads about this topic, but I can't seem to
Wanted to know if someone had a suggestion on code or maybe there's a
I wanted to use 6 different textures on a cube, one per side, but
If someone knew little about databases and wanted to learn about them from scratch,
I was looking at a project that someone wanted done and in order to
i've always wanted to make some of our companies products open-source..but we have a

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.