Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

blocking call

Posted on 2012-12-20
11
Medium Priority
?
341 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
Veeam Task Manager for Hyper-V

Task Manager for Hyper-V provides critical information that allows you to monitor Hyper-V performance by displaying real-time views of CPU and memory at the individual VM-level, so you can quickly identify which VMs are using host resources.

 
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 learning courses: Active Directory Deep Dive

Get a firm grasp on your IT environment when you learn Active Directory best practices with Veeam! Watch all, or choose any amount, of this three-part webinar series to improve your skills. From the basics to virtualization and backup, we got you covered.

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…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.

604 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