Compiling multi-threaded programs with the GNU compiler suite

V

Virchanza

I have a program that's written primarily in C++, and a small portion
of it in C.

My program uses the wxWidgets application framework, which provides
functionality for stuff like graphical user interfaces and multi-
threading (e.g. it provides classes such as wxThread, wxMutex).

wxWidgets is a cross-platform library; it has ports available for
Linux, MacOS and MS-Windows and others. On Unix-like systems,
wxWidgets implements multi-threading by using the "pthreads" library
under the hood, however on MS-Windows it uses the mult-threading
functions provided by the Win32 API.

Since my own program is cross-platform and may be compiled for
different operating systems, I cannot assume that "pthreads" is being
used under the hood.

The small portion of my program that's written in C doesn't contain
any multi-threading code at all. However, since this C code will be
used in my big multi-threaded C++ program, I've made sure that all of
the functions in my C code are re-entrant.

When I use GCC to compile the portion of my program written in C, I
want to tell it that the Standard C Library must be re-entrant because
my C code will get linked into a big multi-threaded C++ program.

....well ...I've searched the web and I've gone through the GNU
documentation but I haven't found a clear-cut answer on how to tell
the GNU compiler that you need a thread-safe implementation of the
Standard C Library.

I've heard some people specify -D _REENTRANT when compiling, but I see
no mention of this macro in the GNU manual.

I compile my entire program in 3 stages. First I compile the C files
to object files:

gcc -c *.c

Next I compile the C++ files to object files:

g++ -c `wx-config --cppflags` *.cpp

Next I use the linker to create an executable file:

g++ `wx-config --libs` *.o -o prog

The command "wx-config --cppflags" on my Ubuntu Linux machine expands
to:

-D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D__WXGTK__

The command "wx-config --libs" on my Ubuntu Linux machine expands to:

-pthread -Wl,-Bsymbolic-functions -lwx_gtk2u_richtext-2.8 -
lwx_gtk2u_aui-2.8 -lwx_gtk2u_xrc-2.8 -lwx_gtk2u_qa-2.8 -
lwx_gtk2u_html-2.8 -lwx_gtk2u_adv-2.8 -lwx_gtk2u_core-2.8 -
lwx_baseu_xml-2.8 -lwx_baseu_net-2.8 -lwx_baseu-2.8

(note that these commands give different outputs on different
operating systems).

Anyway, for now I just want to figure out which multi-threading-
related compiler options I should be specifying. Honestly I've been
searching the web for the last hour and I haven't yet found what I'm
looking for.

The GNU compiler has the "-pthread" switch but that wouldn't be
appropriate to use if my program's being compiled for Win32. I can't
find much info on what _REENTRANT actually does.

Any help?
 
G

Gerhard Fiedler

Virchanza said:
The command "wx-config --libs" on my Ubuntu Linux machine expands to:

-pthread -Wl,-Bsymbolic-functions -lwx_gtk2u_richtext-2.8 -
lwx_gtk2u_aui-2.8 -lwx_gtk2u_xrc-2.8 -lwx_gtk2u_qa-2.8 -
lwx_gtk2u_html-2.8 -lwx_gtk2u_adv-2.8 -lwx_gtk2u_core-2.8 -
lwx_baseu_xml-2.8 -lwx_baseu_net-2.8 -lwx_baseu-2.8

(note that these commands give different outputs on different
operating systems).

Anyway, for now I just want to figure out which multi-threading-
related compiler options I should be specifying. Honestly I've been
searching the web for the last hour and I haven't yet found what I'm
looking for.

The GNU compiler has the "-pthread" switch but that wouldn't be
appropriate to use if my program's being compiled for Win32. I can't
find much info on what _REENTRANT actually does.

AFAIK there are pthread implementations for Windows. However, what
threading lib you need to use seems to depend mostly on what "wx-config
--libs" returns on a Windows platform. You probably should use the same
threading library/API in your code.

(FWIW, I think this is off-topic here. You may have more luck in a
WxWidget or GCC forum.)

Gerhard
 
N

Nobody

Anyway, for now I just want to figure out which multi-threading-
related compiler options I should be specifying. Honestly I've been
searching the web for the last hour and I haven't yet found what I'm
looking for.

The GNU compiler has the "-pthread" switch but that wouldn't be
appropriate to use if my program's being compiled for Win32. I can't
find much info on what _REENTRANT actually does.

"wx-config --cflags" will include -pthread where appropriate.

-D_REENTRANT is a legacy feature from earlier versions of libc; modern
versions don't need it. All glibc functions are re-entrant unless the
API prevents this (e.g. strtok, getpwnam, etc), in which case there's
usually a re-entrant alternative (strtok_r, getpwnam_r, etc).
 
V

Virchanza

"wx-config --cflags" will include -pthread where appropriate.

-D_REENTRANT is a legacy feature from earlier versions of libc; modern
versions don't need it. All glibc functions are re-entrant unless the
API prevents this (e.g. strtok, getpwnam, etc), in which case there's
usually a re-entrant alternative (strtok_r, getpwnam_r, etc).

Hadn't thought of using "--cflags" when compiling the C portion.
Thanks.

This is what I'm looking at now:

gcc -c `wx-config --cflags` *.c
g++ -c `wx-config --cppflags` *.cpp
g++ `wx-config --libs` *.o -o prog
 
M

Michael Doubez

"wx-config --cflags" will include -pthread where appropriate.

-D_REENTRANT is a legacy feature from earlier versions of libc; modern
versions don't need it. All glibc functions are re-entrant unless the
API prevents this (e.g. strtok, getpwnam, etc), in which case there's
usually a re-entrant alternative (strtok_r, getpwnam_r, etc).

Actually, -pthread triggers -_DREENTRANT
You can check it with your gcc:

gcc -dumpspecs | grep pthread
.... %{pthread:-D_REENTRANT} ...
 
V

Virchanza

This should use --cxxflags rather than --cppflags. --cppflags reports the
preprocessor flags.


Thanks again. Where did you get this information from? I've been
searching the web and I can't find anything at all to explain how --
cppflags, --cxxflags and --cflags should be used. (I checked the
wxWidgets manual too).

On my Ubuntu machine, the difference between --cxxflags and --cppflags
is that --cxxflags gives you -pthread. It's interesting that my
program has been working fine all this time even though I never
specified --cxxflags (and hence never specified -pthread).

So now I've got:

gcc -c `wx-config --cflags` *.c
g++ -c `wx-config --cxxflags` *.cpp
g++ `wx-config --libs` *.o -o prog
 
N

Nobody

Thanks again. Where did you get this information from?

1. Those names have a long history. E.g. the various "make" programs have
default rules for generating object files from source files in common
languages, and those rules usually include:

%.o: %.c
$(CC) -c $(CPPFLAGS) $(CFLAGS)

%.o: %.cc
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS)

[similarly for .cpp and .cxx and maybe .c++ and/or .C]

The GNU make manual includes a list of "standard" variables, including:

`CFLAGS'
Extra flags to give to the C compiler.

`CXXFLAGS'
Extra flags to give to the C++ compiler.

...

`CPPFLAGS'
Extra flags to give to the C preprocessor and programs that use it
(the C and Fortran compilers).

The use of "CPP" as an abbreviation for "C PreProcessor" goes back way
before C++ existed, hence the common use of "CXX" where a purely-alphabetic
acronym for C++ is required.

2. The output from wx-config suggests that it follows this convention; the
output from "wx-config --cppflags" only includes options which are
meaningful to the preprocessor (e.g. -I and -D), while --cflags and
--cxxflags include options which are only meaningful to the compiler or
linker (e.g. -pthread).
On my Ubuntu machine, the difference between --cxxflags and --cppflags
is that --cxxflags gives you -pthread.

Technically that's incorrect, as -pthread can set preprocessor options on
some platforms. But usually it only affects the linker. And I don't think
-pthread does anything on Linux/x86.
So now I've got:

gcc -c `wx-config --cflags` *.c
g++ -c `wx-config --cxxflags` *.cpp
g++ `wx-config --libs` *.o -o prog

The last one should really have `wx-config --libs` after *.o, but it
shouldn't matter unless there are static libraries involved.
 
N

Nobody

Actually, -pthread triggers -_DREENTRANT

Right. But defining _REENTRANT has almost no effect with modern
versions of glibc.

Its sole effect is to enable the prototype of getlogin_r() in <unistd.h>
if it wasn't already enabled by __USE_POSIX199506 (e.g. if you used -ansi
and either didn't specifically enable POSIX features or only enabled a
very old version; _GNU_SOURCE will enable it as will _XOPEN_SOURCE >= 500).

ISTR that older versions (i.e. Linux libc5) required _REENTRANT for
features such as per-thread errno. But that's ancient history by now.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top