Compiling multi-threaded programs with the GNU compiler suite

  • Follow


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?
0
Reply virtual (44) 4/4/2011 12:28:35 AM

Virchanza wrote:

> 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
0
Reply gelists (266) 4/4/2011 6:18:01 PM


On Sun, 03 Apr 2011 17:28:35 -0700, Virchanza wrote:

> 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).

0
Reply nobody (4805) 4/4/2011 7:55:15 PM

On Apr 4, 8:55=A0pm, Nobody <nob...@nowhere.com> wrote:

> "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
0
Reply virtual (44) 4/5/2011 12:49:19 AM

On Mon, 04 Apr 2011 17:49:19 -0700, Virchanza wrote:

> This is what I'm looking at now:

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

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

0
Reply nobody (4805) 4/5/2011 4:33:28 AM

On 4 avr, 21:55, Nobody <nob...@nowhere.com> wrote:
> On Sun, 03 Apr 2011 17:28:35 -0700, Virchanza wrote:
> > 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).

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

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

--
Michael
0
Reply michael.doubez (922) 4/5/2011 8:14:40 AM

On Apr 5, 5:33=A0am, Nobody <nob...@nowhere.com> wrote:
> On Mon, 04 Apr 2011 17:49:19 -0700, Virchanza wrote:
> > This is what I'm looking at now:
> > g++ -c `wx-config --cppflags` *.cpp
>
> 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
0
Reply virtual (44) 4/5/2011 10:24:23 PM

On Tue, 05 Apr 2011 15:24:23 -0700, Virchanza wrote:

>> > This is what I'm looking at now:
>> > g++ -c `wx-config --cppflags` *.cpp
>>
>> This should use --cxxflags rather than --cppflags. --cppflags reports the
>> preprocessor flags.
> 
> 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.

0
Reply nobody (4805) 4/6/2011 12:53:54 AM

On Tue, 05 Apr 2011 01:14:40 -0700, Michael Doubez wrote:

>> "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

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.

0
Reply nobody (4805) 4/6/2011 1:00:58 AM

8 Replies
26 Views

(page loaded in 0.117 seconds)

Similiar Articles:










7/9/2012 7:55:59 AM


Reply: