13

The Microsoft Visual C++ compilers have the EnterCriticalSection and ExitCriticalSection objects to allow for synchronization between threads.

What is the GCC equivalent?

I see references around to __sync_synchronize along with __scoped_lock

In fact I see mention of a number of atomic __sync functions along with a number of __atomic ones.

I actually have been using __sync_fetch_and_add for my atomic increment Should I be using __atomic_add_dispatch instead?
What's the difference?

Which ones should I be using? Are there some constructs in C++ that I can use in both the latest version of GCC and Visual C++ 2010 that are available as I'm going to be writing some cross platform code.

I see boost has some functions available, but for various reasons I'm not allowed to use boost under windows.

hookenz
  • 36,432
  • 45
  • 177
  • 286
  • I suppose you cannot use any other library either then? Qt has a nice (cross-platform) threading API. – mtvec Aug 18 '10 at 07:09

4 Answers4

22

On Linux (and other Unixen) you need to use PThreads, or Posix Threads. There is no equivalent to Critical Sections on Windows; use a Mutex instead.

EDIT: See first comment below -- apparently Posix Mutexes are the same as Win32 Critical Sections in that they are bound to a single process.

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
  • 8
    Actually, POSIX mutexes are equivalent to Win32 Critical Sections (process-bounded); Win32 Mutexes differ from Critical Sections in being cross-process. – MSalters Aug 18 '10 at 08:33
  • @MSalters: Ah -- didn't know that. Must smash terminology reuse. – Billy ONeal Aug 18 '10 at 13:17
  • 1
    @MSalters, Also, Win32 Critical Sections are a lot faster than Win32 mutexes because they are implemented in user space and don't involve the overhead associated with system call. I don't know about Posix mutexes though ? – Tanuj Oct 13 '10 at 15:49
  • @Tanuj: You might want to benchmark that statement. Most threading overhead is usually the result of context switches, rather than locking, in any case. – Billy ONeal Oct 13 '10 at 15:53
  • it strongly depends on the contention. On a highly contended lock, context-switching to other threads will dominate. On a lighly contended lock, a context switch between user space and kernel space would dominate (which a Win32 Critical Section avoids in the uncontended case) – MSalters Oct 15 '10 at 07:54
  • 4
    I did some testing, and in heavy contesting conditions by many threads, windows' critical sections are significantly faster than linux mutex – Arsen Zahray Mar 27 '14 at 16:59
  • 3
    @Arsen: Wouldn't have surprised me either way. They're different beasts under the hood, to my (very limited) understanding. I know the Windows guys spent a lot of time optimizing the way locks behave. – Billy ONeal May 07 '14 at 21:15
  • Well linux has futexs which are in userspace and faster than mutexs. I do not know how the speed of these compare to Win32 critical sections. – floomby Nov 28 '21 at 19:48
10

Check here: http://en.wikipedia.org/wiki/Critical_section

/* Sample C/C++, Unix/Linux */
#include <pthread.h>

/* This is the critical section object (statically allocated). */
static pthread_mutex_t cs_mutex =  PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;

void f()
{
    /* Enter the critical section -- other threads are locked out */
    pthread_mutex_lock( &cs_mutex );

    /* Do some thread-safe processing! */

    /*Leave the critical section -- other threads can now pthread_mutex_lock()  */
    pthread_mutex_unlock( &cs_mutex );
}

int main()
{
    f();

    return 0;
}
Tutankhamen
  • 3,532
  • 1
  • 30
  • 38
2

If you are developing programs only for Windows platform, I think the best way is using Win32 API. Otherwise you can use Qt C++ libraries (for that purpose Qt Core is enough).

See also: QMutex and QMutexLocker You can also use: QReadWriteLock

Amith Chinthaka
  • 1,015
  • 1
  • 17
  • 24
2

EnterCriticalSection and the rest of the APIs are Win32 APIs. As far as cross-platform synchronization APIs, I don't think there are any (since you mention you can't use boost). Also, you mentioned cross-platform, does this mean different architectures too (for the gcc part i.e.). I've seen one large implementation where there was a common set of APIs provided which were conditionally compiled to have the native APIs (like fetch_and_add on AIX) or used pthreads the Win32 APIs. I once tried to use posix threads on win32 but ran into a bunch of issues (but that was a very old version). Now YMMV.

Gangadhar
  • 1,893
  • 9
  • 9