[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Linux/pthreads equivalents for Windows API functions

Posted on 2005-04-10
6
Medium Priority
?
8,428 Views
Last Modified: 2010-08-05
I am developing a cross-platform thread library for use with a card game server that I am designing.  I am familar with programming threads in Java and Windows API.  I would like to implement a synchronization construct similar to Windows event handles (HANDLE CreateEvent(...) in Windows API or Object.wait() / Object.notify()  in Java).  However, the examples I have seen for "condition variables" (if that is the equivalent) are confusing to me.  I do not understand the need to associate the additional mutex with the condition variable.

Once the condition is signaled, when does it get reset?  Is there any way to affect when they get reset?

Also, is there any pthreads equivalent for ::WaitForMultipleObjects(...) ?  If not, any ideas on implementing something similar?

Thanks,

Shawn

0
Comment
Question by:ShawnCurry
  • 3
  • 2
6 Comments
 
LVL 30

Expert Comment

by:Axter
ID: 13750599
Can you show an example as to how you're using WaitForMultipleObjects?

I'm sure there's a way to duplicate the logic requirements using POSIX functions.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 13751526
The equivalent to pthread_mutex_t in Windows is a CriticalSection (fast mutex, not nestable, one process only) or a Mutex (processes and threads, nestable).

With both you could control an arbitrary resource, so that only one thread has exclusive access and all others that try to access while the resource is exclusively locked have to wait til unlock:

#ifdef PTHREAD
#   include <pthread.h>
    /*
     *  thread and mutex types
     */
    typedef pthread_t            Thread;
    typedef pthread_mutex_t  ThreadMutex;
#elif defined (WIN32)
    typedef unsigned long             Thread;
    typedef CRITICAL_SECTION    ThreadMutex;
#endif


/* one time initialization of a 'fast' mutex (not reversible) */
void initMutex(void* pMutex)
{
#if defined (PTHREAD)
     pthread_mutex_init((pthread_mutex_t*)pMutex, pthread_mutexattr_default);
#elif defined (WIN32)
     InitializeCriticalSection((PCRITICAL_SECTION)pMutex);
#endif
}

/* enter critical section and block others threads or wait                              */
void enterMutex(void* pMutex)
{
#if defined (PTHREAD)
     pthread_mutex_lock((pthread_mutex_t*)pMutex);
#elif defined (WIN32)
     EnterCriticalSection((PCRITICAL_SECTION)pMutex);
#endif
}
     
/* leave critical section and release any other thread blocked                         */
void leaveMutex(void* pMutex)
{
#if defined (PTHREAD)
     pthread_mutex_unlock((pthread_mutex_t*)pMutex);
#elif defined (WIN32)
     LeaveCriticalSection((PCRITICAL_SECTION)pMutex);
#endif
}


You would use this like:


ThreadMutex mutex;   // create global mutex

int main()
{
        initMutex(&mutex);

       // start some threads ...

       while (true)
       {
              doSomething();
              if (needToWriteToLogFile())
              {
                    // either we get the resource (logfile) exclusively or we have to wait
                    enterMutex(&mutex);
                   
                    ofstream oflog("logfile.log", ios::append | ios::out);
                    writeLog(oflog, "Any message");
                    oflog.close();
         
                    leaveMutex(&mutex);
              }
       }
 }
   

// thread.cpp

void threadFunction(void* pParam)
{
       while (true)
       {
              doSomeThreadThings();
              if (needToWriteToLogFile())
              {
                    // either we get the resource (logfile) exclusively or we have to wait
                    enterMutex(&mutex);
                   
                    ofstream oflog("logfile.log", ios::append | ios::out);
                    writeLog(oflog, "Any message");
                    oflog.close();
         
                    leaveMutex(&mutex);
              }
       }
}


Regards, Alex
0
 
LVL 3

Author Comment

by:ShawnCurry
ID: 13753418
Thanks for the quick reply.  I quickly found the relationship between CRITICAL_SECTION's and pthread_mutex_t's on my own (in fact, my code is much simpler ;) .  It is pthread_cond_t's which are confusing to me.  I would like to see a similar example implementing the producer/consumer paradigm with a boundless queue, or perhaps an explanation about when the condition gets reset.  Here is some pseudo-code for what I would like to achieve:

Main thread:

Create auto-reset (read) event
Create manual-reset (write) event
Create one producer
Create serveral consumers

Producer thread:

if ( wants to add )
{
    reset manual (write) event (set to unsignalled)
    wait for auto-reset (read) event
    add item
    signal both events
}

Consumer thread:

if( wants to remove )
{
    wait for both events   // This is where I would use WaitForMultipleObjects() in Windows API
    remove item
    signal auto-reset (read) event
}

In Windows, this pattern creates sort of a "priority flag" for the producer thread - once the 'write' event is unsignalled, the producer thread is guaranteed to be the next to run, because consumer threads will wait until the 'write' event is signalled.

WaitForMultipleObjects() in Windows may be used to wait for an entire array of events to become signalled or threads to complete, or to wait for just one in the set, much the same way as the select() sockets function works.  I would like to use it both ways.  It has occurred to me that perhaps the select() function itself might be used, but I have not had a chance to test my theory yet.

Thanks,
Shawn
0
Independent Software Vendors: 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 39

Accepted Solution

by:
itsmeandnobodyelse earned 500 total points
ID: 13753739
>>>> in fact, my code is much simpler ;)

Portable code as well?

>>>> Here is some pseudo-code for what I would like to achieve

The pseudo code most likely would dead-lock as the main thread (Producer) doesn't wait on auto-reset (read) event all the time *but* only if "wants to add".

Actually, it seems to me that events isn't optimal to meet the requirements. Events normally are used for performance reasons: to be able to signal an event where one or more threads are waiting on *not* having to poll in an infinite loop. Of course you could use events to protect a shared resource, but a critical section is much cheaper (and more robust). Note, you could make a critical section object a class member of a container class - say a queue class. Then you could use it to make all remove and insert (query, iterators, ...) functions of that queue thread-safe, simply by adding an 'enter' at the beginning and a 'leave' at the end of these member functions. Thus, your threads could arbitrarily use that container and if some of them try to access nearly same time, they automatically wait til the resource gets free again. And you have to add *nothing* in the thread code to get thread-safety.

Regards, Alex
0
 
LVL 3

Author Comment

by:ShawnCurry
ID: 13759022
>> Portable code as well?

I apologize, I did not mean sound critical of your code.  In fact, it's really the same code, I just like to define macros up front instead of mixing #ifdefs into my functions, if possible (and it was).

>> Actually, it seems to me that events isn't optimal to meet the requirements.

I do understand the uses for events.  I agree that a mutex would probably be a better fit for my example.  Truly, the point of the discussion is that I do not completely understand how pthread_cond_t's work.  I would like to have a synchronization construct in my library which implements the wait() / notify() paradigm.  In Windows, I use an event handle.  The functions which operate on pthread_cond_t's seem like they could be used, but I just don't see how it actually works.  I suppose I'll just have to get used to it.

I've found an interesting article on implementing windows style event handles and WaitForMultipleObjects() using POSIX threads:

http://developers.sun.com/solaris/articles/waitfor_api.pdf

Thanks for your help so far, I'll leave the topic open for discussion for a few days.

Shawn
0
 
LVL 3

Author Comment

by:ShawnCurry
ID: 13882171
Sorry for the long wait.  I picked up a few very useful books: "Programming with POSIX Threads", D. Butenhof; and "UNIX Network Programming", W. Stevens.  These books were recommended to me as "The Bible"; and indeed they are.

Thanks anyway,

Shawn
0

Featured Post

Independent Software Vendors: 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!

Question has a verified solution.

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

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
Suggested Courses

873 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