summaryrefslogtreecommitdiff
path: root/FAQ
blob: 8c826f55d65025042d246ba8da77d0231a11c8be (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
                  =========================================
                  PTHREADS-WIN32 Frequently Asked Questions
                  =========================================

INDEX
-----

Q 1	What is it?

Q 2	Which of the several dll versions do I use?
	or,
	What are all these pthread*.dll and pthread*.lib files?

Q 3	What is the library naming convention?

Q 4	Cleanup code default style or: it used to work when I built
	the library myself, but now it doesn't - why?

Q 5	Why is the default library version now less exception-friendly?

Q 6	Should I use Cygwin or Mingw32 as a development environment?

Q 7	Now that pthreads-win32 builds under Mingw32, why do I get
	memory access violations (segfaults)?

Q 8	How do I use pthread.dll for Win32 (Visual C++ 5.0)

Q 9	Cancelation doesn't work for me, why?

Q 10	Thread won't block after two calls to mutex_lock

Q 11	How do I generate pthreadGCE.dll and libpthreadw32.a for use with Mingw32?

=============================================================================

Q 1	What is it?
---

Pthreads-win32 is an Open Source Software implementation of the
Threads component of the POSIX 1003.1c 1995 Standard for Microsoft's
Win32 environment. Some functions from POSIX 1003.1b are also
supported including semaphores. Other related functions include
the set of read-write lock functions. The library also supports
some of the functionality of the Open Group's Single Unix
specification, version 2, namely mutex types.

See the file "ANNOUNCE" for more information including standards
conformance details and list of supported routines.


Q 2	Which of the several dll versions do I use?
---	or,
	What are all these pthread*.dll and pthread*.lib files?

Simply, you only use one of them, but you need to choose carefully.

The most important choice you need to make is whether to use a
version that uses exceptions internally, or not (there are versions
of the library that use exceptions as part of the thread
cancelation and exit implementation, and one that uses
setjmp/longjmp instead).

There is some contension amongst POSIX threads experts as
to how POSIX threads cancelation and exit should work
with languages that include exceptions and handlers, e.g.
C++ and even C (Microsoft's Structured Exceptions).

The issue is: should cancelation of a thread in, say,
a C++ application cause object destructors and C++ exception
handlers to be invoked as the stack unwinds during thread
exit, or not?

There seems to be more opinion in favour of using the
standard C version of the library (no EH) with C++ applications
since this appears to be the assumption commercial pthreads
implementations make. Therefore, if you use an EH version
of pthreads-win32 then you may be under the illusion that
your application will be portable, when in fact it is likely to
behave very differently linked with other pthreads libraries.

Now you may be asking: why have you kept the EH versions of
the library?

There are a couple of reasons:
- there is division amongst the experts and so the code may
  be needed in the future. (Yes, it's in the repository and we
  can get it out anytime in the future, but ...)
- pthreads-win32 is one of the few implementations, and possibly
  the only freely available one, that has EH versions. It may be
  useful to people who want to play with or study application
  behaviour under these conditions.


Q 3	What is the library naming convention?
---

Because the library is being built using various exception
handling schemes and compilers - and because the library
may not work reliably if these are mixed in an application,
each different version of the library has it's own name.

Note 1: the incompatibility is really between EH implementations
of the different compilers. It should be possible to use the
standard C version from either compiler with C++ applications
built with a different compiler. If you use an EH version of
the library, then you must use the same compiler for the
application. This is another complication and dependency that
can be avoided by using only the standard C library version.

Note 2: if you use a standard C pthread*.dll with a C++
application, then any functions that you define that are
intended to be called via pthread_cleanup_push() must be
__cdecl.

Note 3: the intention is to also name either the VC or GC
version (it should be arbitrary) as pthread.dll, including
pthread.lib and libpthread.a as appropriate.

In general:
	pthread[VG]{SE,CE,C}.dll
	pthread[VG]{SE,CE,C}.lib

where:
	[VG] indicates the compiler
	V	- MS VC
	G	- GNU C

	{SE,CE,C} indicates the exception handling scheme
	SE	- Structured EH
	CE	- C++ EH
	C       - no exceptions - uses setjmp/longjmp

For example:
	pthreadVSE.dll	(MSVC/SEH)
	pthreadGCE.dll	(GNUC/C++ EH)
	pthreadGC.dll   (GNUC/not dependent on exceptions)

The GNU library archive file names have changed to:

	libpthreadGCE.a
	libpthreadGC.a


Q 4	Cleanup code default style or: it used to work when I built
---	the library myself, but now it doesn't - why?

Up to and including snapshot 2001-07-12, if not defined, the cleanup
style was determined automatically from the compiler used, and one
of the following was defined accordingly:

	__CLEANUP_SEH	MSVC only
	__CLEANUP_CXX	C++, including MSVC++, GNU G++
	__CLEANUP_C		C, including GNU GCC, not MSVC

These defines determine the style of cleanup (see pthread.h) and,
most importantly, the way that cancelation and thread exit (via
pthread_exit) is performed (see the routine ptw32_throw() in private.c).

In short, the exceptions versions of the library throw an exception
when a thread is canceled or exits (via pthread_exit()), which is
caught by a handler in the thread startup routine, so that the
the correct stack unwinding occurs regardless of where the thread
is when it's canceled or exits via pthread_exit().

After snapshot 2001-07-12, unless your build explicitly defines (e.g.
via a compiler option) __CLEANUP_SEH, __CLEANUP_CXX, or __CLEANUP_C, then
the build now ALWAYS defaults to __CLEANUP_C style cleanup. This style
uses setjmp/longjmp in the cancelation and pthread_exit implementations,
and therefore won't do stack unwinding even when linked to applications
that have it (e.g. C++ apps). This is for consistency with most/all
commercial Unix POSIX threads implementations.

Although it was not clearly documented before, it is still necessary to
build your application using the same __CLEANUP_* define as was
used for the version of the library that you link with, so that the
correct parts of pthread.h are included. That is, the possible
defines require the following library versions:

	__CLEANUP_SEH	pthreadVSE.dll
	__CLEANUP_CXX	pthreadVCE.dll or pthreadGCE.dll
	__CLEANUP_C		pthreadVC.dll or pthreadGC.dll

THE POINT OF ALL THIS IS: if you have not been defining one of these
explicitly, then the defaults have been set according to the compiler
and language you are using, as described at the top of this
section.

THIS NOW CHANGES, as has been explained above. For example:

If you were building your application with MSVC++ i.e. using C++
exceptions (rather than SEH) and not explicitly defining one of
__CLEANUP_*, then __CLEANUP_C++ was defined for you in pthread.h.
You should have been linking with pthreadVCE.dll, which does
stack unwinding.

If you now build your application as you had before, pthread.h will now
set __CLEANUP_C as the default style, and you will need to link
with pthreadVC.dll. Stack unwinding will now NOT occur when a
thread is canceled, nor when the thread calls pthread_exit().

Your application will now most likely behave differently to previous
versions, and in non-obvious ways. Most likely is that local
objects may not be destroyed or cleaned up after a thread
is canceled.

If you want the same behaviour as before, then you must now define
__CLEANUP_C++ explicitly using a compiler option and link with
pthreadVCE.dll as you did before.


Q 5	Why is the default library version now less exception-friendly?
---

Because no commercial Unix POSIX threads implementation allows you to
choose to have stack unwinding. Therefore, providing it in pthread-win32
as a default is dangerous. We still provide the choice but 
you must now consciously make it.

WHY NOT REMOVE THE EXCEPTIONS VERSIONS OF THE LIBRARY ALTOGETHER?
There are a few reasons:
- because there are well respected POSIX threads people who believe
  that POSIX threads implementations should be exceptions-aware and
  do the expected thing in that context. (There are equally respected
  people who believe it should not be easily accessible, if it's there
  at all.)
- because pthreads-win32 is one of the few implementations that has
  the choice, perhaps the only freely available one, and so offers
  a laboratory to people who may want to explore the effects;
- although the code will always be around somewhere for anyone who
  wants it, once it's removed from the current version it will not be
  nearly as visible to people who may have a use for it.


Q 6	Should I use Cygwin or Mingw32 as a development environment?
---

Important: see Q7 also.

In short, use Mingw32 with the MSVCRT library to build applications that use
the DLL. Cygwin's own internal support for POSIX threads is growing. Consult
that project's documentation for more information.

Date: Mon, 07 Dec 1998 15:11:37 +0100
From: Anders Norlander <anorland@hem2.passagen.se>
To: Ross Johnson <rpj@ise.canberra.edu.au>
Cc: pthreads-win32 <pthreads-win32@air.net.au>
Subject: Re: pthreads-win32: TryEnterCriticalSection patch (fwd)

Ross Johnson wrote:
> 
> Anders,
> 
> You said you're using GCC. Is that from cygwin32 or mingw32? What is your
> environment (so I can perhaps help other people out)? We have problems
> with cygwin32 et al that have been built on Win95. They're missing
> _{begin,end}threadex.

Ross,

I use mingw32 when compiling pthreads-win32, but unlike most people I
use MSVCRT as the C library instead of CRTDLL. For those that don't
feel like configuring and building the necessary components themselves,
Mumit Khan has released an add on for mingw32 to make it use MSVCRT40.
It is available at his ftp site, follow the minw32 links at
http://www.xraylith.wisc.edu/~khan/software/gnu-win32/

For cygwin it is a completely different matter. I suppose
pthreads-win32 uses _beginthreadex and _endthreadex because the Win32
docs say that programs calling functions in the C library should not
use CreateThread and ExitThread. However, this applies only to
Microsoft's (and possibly others) multithreaded C libraries that need
to keep track of per thread data, it does not apply to cygwin.
This code solves the problem:

/* Check for old and new versions of cygwin */
#if defined(__CYGWIN32__) || defined(__CYGWIN__)
/* Macro uses args so we can cast start_proc to LPTHREAD_START_ROUTINE
   in order to avoid warnings because of return type */
#define _beginthreadex(security, stack_size, start_proc, arg, flags,
pid) \
CreateThread(security, stack_size, (LPTHREAD_START_ROUTINE) start_proc,
\
             arg, flags, pid)
#define _endthreadex ExitThread
#endif

I would be extremely careful using threads with cygwin, since it is
not (yet) threadsafe.

Regards,
Anders

------------------------------------------------------------------------------

Q 7	Now that pthreads-win32 builds under Mingw32, why do I get
---	memory access violations (segfaults)?

Note: issue resolved.
The latest Mingw32 package has thread-safe exception handling.
Make sure you also read A 6 below to get a fully working build.


The following email exchange describes the problem. Until this issue
is resolved people without the Microsoft compiler can obtain the current
MSVC prebuilt DLL (pthread.{dll,lib,h}) at:

ftp://sources.redhat.com/pub/pthreads-win32/dll-latest 

Date: Wed, 10 Feb 1999 13:21:01 -0000
From: "Ruland, Kevin" <Kevin.Ruland@anheuser-busch.com>
Reply-To: POSIX threads on Win32 <pthreads-win32@air.net.au>
To: 'POSIX threads on Win32' <pthreads-win32@air.net.au>
Subject: Mingw32 exceptions not thread safe.

Hello everyone.

I asked Mumit Khan, maintainer of egcs for mingw and assorted guru, about
the Known Problem listed below.  

> Known problems
> --------------
> 
> There is an unresolved bug which shows up as a segmentation fault
> (memory access violation) when the library is built using g++. Build
> the test program "eyal1.c" and run with an argument of "2" or
> greater. The argument is the number of threads to run, excluding the
> main thread, so the bug appears with 2 or more worker threads.
> 
> Kevin Ruland has traced the exception to the try/catch blocks in
> ptw32_threadStart().
> 

The official word is:

<Quote Mumit Khan [khan@xraylith.wisc.edu]>
EGCS-1.1.1 for win32 (either cygwin or crtdll/msvc runtimes) do not have
thread-safe exception support. 

For Cygwin, it'll happen when Cygwin runtime has mature thread safety and
pthread is fully integrated. Then it's just a matter of rebuilding GCC (or
just libgcc in this) with thread safe EH support.

For Mingw crtdll/msvc, someone needs to write the thread-wrapper for win32
threads. Anyone who knows win32 threads should be able to do this without
much trouble at all. It's low on my priority list, so unless someone else
volunteers, it'll have to wait.
<\Quote>

Kevin

------------------------------------------------------------------------------

Q 8	How do I use pthread.dll for Win32 (Visual C++ 5.0)
---	

>
> I'm a "rookie" when it comes to your pthread implementation.  I'm currently
> desperately trying to install the prebuilt .dll file into my MSVC compiler.
> Could you please provide me with explicit instructions on how to do this (or
> direct me to a resource(s) where I can acquire such information)?
>
> Thank you,
>

You should have a .dll, .lib, .def, and three .h files.

The .dll can go in any directory listed in your PATH environment
variable, so putting it into C:\WINDOWS should work.

The .lib file can go in any directory listed in your LIB environment
variable.

The .h files can go in any directory listed in your INCLUDE
environment variable.

Or you might prefer to put the .lib and .h files into a new directory
and add its path to LIB and INCLUDE. You can probably do this easiest
by editing the file:-

C:\Program Files\DevStudio\vc\bin\vcvars32.bat

The .def file isn't used by anything in the pre-compiled version but 
is included for information.

Cheers.
Ross

------------------------------------------------------------------------------

Q 9	Cancelation doesn't work for me, why?
---

> I'm investigating a problem regarding thread cancelation. The thread I want
> to cancel has PTHREAD_CANCEL_ASYNCHRONOUS, however, this piece of code
> blocks on the join():
>
>               if ((retv = Pthread_cancel( recvThread )) == 0)
>               {
>                       retv = Pthread_join( recvThread, 0 );
>               }
>
> Pthread_* are just macro's; they call pthread_*.
>
> The thread recvThread seems to block on a select() call. It doesn't get
> cancelled.
>
> Two questions:
>
> 1) is this normal behaviour?
>
> 2) if not, how does the cancel mechanism work? I'm not very familliar to
> win32 programming, so I don't really understand how the *Event() family of
> calls work.

Async cancelation should be in versions post snapshot-1999-11-02
of pthreads-win32 (currently only for x86 architectures).

The answer to your first question is, normal POSIX behaviour would  
be to asynchronously cancel the thread. However, even that doesn't
guarantee cancelation as the standard only says it should be
cancelled as soon as possible.

However ...

Snapshot 99-11-02 or earlier only partially supports asynchronous cancellation.
Snapshots since then simulate async cancelation by poking the address of
a cancelation routine into the PC of the threads context. This requires
the thread to be resumed in some way for the cancelation to actually
proceed. This is not true async cancelation, but it is as close as we've
been able to get to it.

If the thread you're trying to cancel is blocked (for instance, it could be
waiting for data from the network), it will only get cancelled when it unblocks
(when the data arrives). Unfortunately, there is no way to do so from
outside the thread.

Using deferred cancelation would normally be the way to go, however,
even though the POSIX threads standard lists a number of C library
functions that are defined as deferred cancelation points, there is
no hookup between those which are provided by Windows and the
pthreads-win32 library.

Incidently, it's worth noting for code portability that the POSIX
threads standard list doesn't include "select" because (as I read in
Butenhof) it isn't part of POSIX.

Effectively, the only cancelation points that pthreads-win32 can
recognise are those the library implements itself, ie.
        
        pthread_testcancel
        pthread_cond_wait
        pthread_cond_timedwait
	pthread_join
        sem_wait
        pthread_delay_np

Pthreads-win32 also provides two functions that allow you to create
cancelation points within your application, but only for cases where
a thread is going to block on a Win32 handle. These are:

        pthreadCancelableWait(HANDLE waitHandle) /* Infinite wait */
 
        pthreadCancelableTimedWait(HANDLE waitHandle, DWORD timeout)

Regards.
Ross

------------------------------------------------------------------------------
 
Q 10	Thread won't block after two calls to mutex_lock
----

> i was testing this pthread for win32 in my prog.
> when i checked if it was blocking mutex_lock calls, i was surprised when it
> didnt lock
> 
> pthread_mutex_t DBlock;
> 
> pthread_mutex_init( &DBlock, NULL );
> pthread_mutex_lock( &DBlock );
> pthread_mutex_lock( &DBlock );
> 
> ^^ these two calls didnt block

POSIX leaves the result "undefined" for a thread that tries
to recursively lock the same mutex (one that it owns already).
That means the actual semantics are left up to the
implementation, but should not be relied upon for code that
will be ported to different POSIX threads implementations.

In the pthreads-win32 implementation a thread won't deadlock
itself by relocking the mutex. Subsequent calls to
pthread_mutex_lock() as in your example above increment
the lock count but the thread continues on. Consequently,
the thread must ensure that it unlocks the mutex once for
each lock operation. That is, pthreads-win32 mutexes are
always recursive.

You may want to look at the other synchronisation devices
available in the library, such as condition variables or
read-write locks.

Ross

------------------------------------------------------------------------------
 
Q 11	How do I generate pthreadGCE.dll and libpthreadw32.a for use with Mingw32?
----

Once you've followed Thomas Pfaff's instructions below to fix
Mingw32, then you can simply run "make" to build the library and dll.


From - Sat Dec  9 22:56:10 2000
From: "Thomas Pfaff" <tpfaff@gmx.net>
To: <mingw-users@lists.sourceforge.net>, <pthreads-win32@sources.redhat.com>
Subject: mingw32 DLLs, threads and exceptions HOWTO
Date: Thu, 7 Dec 2000 11:12:43 +0100

Dear all,

this is a summary that should help users to have thread safe exception
handling over DLL exported functions.
If you don't care about c++ exceptions you can stop reading here.

The first time i struggled with c++ exceptions was when i tried to throw an
exception in a dll exported function where the exception handler resides in
the program module.
Instead of catching the exception the program stopped with an abnormal
termination.
The reason was that the exception code is in libgcc.a. Since this is a
static library the code and some static variables are both in the dll and in
the program module, each module runs in its own context.
It was Franco Bez that pointed me in the right direction, that is convert
libgcc.a into a dll.

That done i tried to build the pthreads-win32 library, but some tests failed
with an access violation. Due to the fact that the dll was not build
was -mthreads support, eh_context_static instead of eh_context_specific (the
mthreads version) was used for exception handling.
I did a rebuild of the gcc dll with -mthreads, now all tests are passed
(except a nonportable exception test that relies on a MSVC feature).

To build the gcc dll i did the following steps.

1. create a temporary directory libgcc
2. copy libgcc.a from gcc-2.95.2\lib\gcc-lib\i386-mingw32\gcc-2.95.2 to that
directory
3. ar -x libgcc.a
4. create a directory tmp and move __main.o, _exit.o and __dummy.o in that
directory
5. build the dll
gcc -shared -mthreads -o gcc.dll *.o
strip gcc.dll
Move this dll into your gcc\bin directory
6. Move _chkstk.o and frame.o to the tmp directory, otherwise you break the
builtin alloca.
7. Build the import library libgcc.a
dllwrap --export-all --dllname=gcc.dll --output-def=libgcc.def --output-lib=
libgcc.a *.o
ar -q libgcc.a tmp/*.o
strip --strip-debug libgcc.a
ranlib libgcc.a
8. save your old libgcc.a, copy the new libgcc.a into
gcc-2.95.2\lib\gcc-lib\i386-mingw32\gcc-2.95.2

I am using gcc-2.95.2-1 with Mumits patched binutils-19990818-1and msvcrt
runtime-2000-03-27.
I don't know if this is still required with the current binutils and gcc
since i have seen no sources until now.

I believe that these steps are at least necessary if you are trying to use
the pthreads-win32 library (which is required if you want to use gtk+ on
win32).
They will make mingw32 a real replacement for MSVC (at least for me).

What is left:

1. Include the mingwm10.dll function into the gcc.dll to have only one dll
left.
2. make -mthreads and -fnative-struct default compiler options.
3. convert libstdc++ to a dll by adding the declspec dllexport and dllimport
to every class definition.

Regards,
    Thomas

------------------------------------------------------------------------------