?
Solved

blocking call

Posted on 2012-12-20
11
Medium Priority
?
338 Views
Last Modified: 2013-01-21
I need to implement a class based on a blocking call using pthreads

My class blocks for event coming from the network:

 My class is like that :

EventHandler
{
     public void waitForEvent1(){
       
// blocks waiting for event 1 from the network
   
    }
   
    SendEvent2 ( Event1) {
     
        perform some action based on Event1 and send response

  }

public void WaitForEvent2


.etc
   


I m thinking about implementing a blocking queue , is the right solution ?

How to do that using pThreads ?



}

Thx
0
Comment
Question by:bachra04
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
11 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 38713752
What kind of event are you thinking about, since you wrote "from the network"?
0
 
LVL 2

Author Comment

by:bachra04
ID: 38714953
some SIP packets coming from remote end point
0
 
LVL 2

Author Comment

by:bachra04
ID: 38716459
one simple solution I have in mind is to use a blocking queue :

so my method will be :

BlockingQueue _queue;

public void WaitForMyEvent ()
{
    Event event;
    _queue.Get ( event);
   
  //  take some action based on the contents of the event

}

My Blocking queue is something like in  the following example :

Blocking Queue with PThread

This may do the job, but I need some advice from the experts about a better solution or more refined one.

Thanks.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 35

Expert Comment

by:Duncan Roe
ID: 38733866
Linux has always had the poll and select system calls to enable i/o multiplexing without the need for multiple threads. Microsoft never had that (except select for sockets only, if you really read the documentation carefully) so they now push dumbed-down multithreading as a solution (is your background MS by the way?).
Nowadays I would use poll. select has to be there to implement the BSD socket interface but I find poll easier to use. For documentation, see
man 2 poll
man 2 select
0
 
LVL 35

Expert Comment

by:sarabande
ID: 38739677
a call which might block forever isn't a good design even if you move it to a thread.

if your main thread would like to exit, you would (need to) kill the blocking thread what could cause lossing resources or - worse - data corruption (depending on os and what the thread does when handling data).

so i would support duncan_roe's comment that multi-threading is not necessarily a solution though you could have multi-threading and nevertheless avoid blocking calls.

the easiest way to avoid blocking probably is to make the socket non-blocking. if you do so, any call to read from socket would return immediately and the return value would tell whether the read was successful or has failed. in case of failing (what is almost every time the case if you do the read call in a loop) you would check a global error (errno on linux, WSAGetLastError() on windows) whether the failing was because of avoiding blocking only (EWOULDBLOCK). you then would repeat the call in periods (polling) until you get a success.

You don't need a separate thread for that. you very well could do the periodical read in a idle time if for example you were running a message pump (ui). but an own thread which does nothing but reading from non-blocking socket and sends a message to the main thread on success is a clean and reasonable design pattern. you would have a little timeout between the reads (in order to take the load off the cpu) and would make the thread stoppable from the main thread in the pauses.

there is a similar design possible when using select (as mentioned from duncan_roe). i would prefer select over poll even if it is not quite so convenient to make your code portable. when using select you would let the socket blockable but before any read from the socket you would call select with a timeout argument to check whether the socket "has" any data. the select call would break with success when there is data or would break with failure when the time-out has expired. so you could implement the same design as described with non-blockable sockets by simply avoiding reads when there is no data to read.

Sara
0
 
LVL 2

Author Comment

by:bachra04
ID: 38782925
I m using this design for testing purposes , writing test cases and not for production. That's why I don't think it is too bad. The other thing is that I m not dealing directly with a socket. I m using a stack that manages the transport layer.
My problem is how to build my own queue data structure or use an existing one.
0
 
LVL 35

Accepted Solution

by:
sarabande earned 2000 total points
ID: 38783693
You could use a simple std::vector<Event> as queue and protect push_back and pop_front functions by a pthread_mutex.

so, whenever an event drops in thread you lock the queue by locking the mutex and push the event to the back of the queue.

when your main thread has idle time it also locks the queue and pops an event from font of queue (index 0) - if any.

because of the mutex neither insert nor removing of event (data) would be unsafe.

Sara
0
 
LVL 2

Author Comment

by:bachra04
ID: 38797605
I have found a link to something that I can use.

http://stackoverflow.com/questions/4577961/pthread-synchronized-blocking-queue

Can any one give me a sample code on how to use this queue since I m not very familiar with C coding ?

Thanks
0
 
LVL 2

Author Closing Comment

by:bachra04
ID: 38799286
I eventually get it working. now I want to get the blocking call executed inside a separate thread ( in order not to block other parts of the program), any help on how to do that using pthread ?

Thanks
0
 
LVL 35

Expert Comment

by:sarabande
ID: 38802475
you create the thread by calling pthread_create. you would pass a pointer to class or struct where at least the queue container and the mutex is a member of. that way both the main thread and the worker thread could share the container and can get exclusive access to the container:

class EventData
{
    // add members for your data and functions to access the data
    // if possible use fixed sized pod members (c types, no pointers).
};

struct ThreadData
{
     std::vector<EventData*> event_queue;
     pthread_mutex_t mux;
     bool stop;
     static void threadfunc(void *);
};



int main(....)
{
      ...
       
      ThreadData data;
      // init data 
      
      ...
      pthread_create( &thread, NULL, ThreadData::threadfunc, &data); 

      while (true)
      {
            // check for user messages
            ...
            // do idle processing
            ...
                  EventData * pEvent = NULL;
                  pthread_mutex_lock(&data.mux);
                  if (!data.event_queue.empty())
                  {
                        pEvent = data.event_queue[0];
                        data.event_queue.erase(data.event_queue.begin());
                  } 
                  pthread_mutex_unlock(&data.mux);
                  if (pEvent)
                       HandleEvent(pEvent);
                  ...

void ThreadData::threadfunc(void * parg)
{
      ThreadData * pdata  = (ThreadData *)parg;       
      while (!pdata->stop)
      {
              EventData pEvent = ReceiveEvent(...);
              if (pEvent != NULL)
              {
                    // lock the queue
                  pthread_mutex_lock(&pdata->mux);
                  pdata->event_queue.push_back(pEvent);
                  pthread_mutex_unlock(&pdata->mux);
              }
              // sleep a little amount of time
      }
}

Open in new window

0
 
LVL 2

Author Comment

by:bachra04
ID: 38802564
Thank you very much Sarabande that definitely answers my question.
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
Suggested Courses

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question