nPth - The new GNU portable threads library
From: | Werner Koch <wk-AT-gnupg.org> | |
To: | gnupg-announce-AT-gnupg.org | |
Subject: | nPth - The New GNU Portable Threads Library | |
Date: | Tue, 08 May 2012 12:39:49 +0200 | |
Message-ID: | <87zk9j2byi.fsf@vigenere.g10code.de> | |
Cc: | marcus.brinkmann-AT-rub.de | |
Archive‑link: | Article |
Hi! We are pleased to announce the first tarball release of the New GNU Portable Threads Library: nPth version 0.90. nPth is a non-preemptive threads implementation using an API very similar to the one known from GNU Pth. It has been designed as a replacement of GNU Pth for non-ancient operating systems. In contrast to GNU Pth is is based on the system's standard threads implementation. Thus nPth allows the use of libraries which are not compatible to GNU Pth. GNU Pth is often used to provide a co-routine based framework. GnuPG-2 makes heavy use of this concept for good audibility, general security concerns, and ease of implementation. However, GNU Pth has the drawback that ugly hacks are required to work with libraries which are not GNU Pth aware. The nPth tarball and its signature are available as ftp://ftp.gnupg.org/gcrypt/npth/npth-0.90.tar.bz2 ftp://ftp.gnupg.org/gcrypt/npth/npth-0.90.tar.bz2.sig and at all GnuPG mirrors. See the included README file and the npth.h header for documentation. Bug reports and requests for help should be send to the gnupg-devel mailing list at gnupg.org. nPth is available under the terms of the LGPLv3+ or the GPLv2+. The GIT repository is at git://git.gnupg.org/npth.git . The current development version of GnuPG (2.1) has already been migrated to nPth and thus the next beta release will require it. Obviously we expect to fix some portability problems before we can release 1.0. On common Linux and kFreeBSD systems and even on Android, nPth should build and work fine. Background: When porting GnuPG-2 to Windows in 2004, we had the need for a replacement of GNU Pth, which is not available for native Windows. We came up with an emulation based on the native Windows thread system. Experience since then showed that such an emulation is a solid way to provide a co-routine based framework. Given that thread implementations (in particular pthreads) are now in common use on all platforms, there is not must justification left for not using them: Without considering the GnuPG packages, Debian has only two packages requiring GNU Pth (zhcon and jabberd14 - the latter even seems not in wide use anymore). Many thanks to Ralf S. Engelschall for his excellent GNU PTH library, which served GnuPG very well for many years. Happy hacking, Marcus and Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. _______________________________________________ Gnupg-announce mailing list Gnupg-announce@gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-announce
Posted May 8, 2012 17:26 UTC (Tue)
by geertj (guest, #4116)
[Link] (21 responses)
Threads on the other hand offer neither. Locking requirements makes them hard to get right, and they eat up a lot of resources making e.g. DoS attacks on thread-based web servers easy.
If you combine coroutines with multiple worker processes, it also allows you to use multiple cores.
I recently did a MIT licensed co-routine library for C/C++:
Posted May 8, 2012 17:39 UTC (Tue)
by endecotp (guest, #36428)
[Link] (1 responses)
Boost has a proposal for a coroutine library by Oliver Kowalke which should be reviewed sometime in the next few months. See e.g.
http://ok73.ok.funpic.de/boost/libs/coroutine/doc/html/in...
It would be great if you could write a review when the time comes - getting the view of someone with relevant experience is obviously very useful.
Posted May 9, 2012 20:42 UTC (Wed)
by kjp (guest, #39639)
[Link]
Posted May 8, 2012 17:46 UTC (Tue)
by juliank (guest, #45896)
[Link] (10 responses)
Posted May 8, 2012 17:59 UTC (Tue)
by fuhchee (guest, #40059)
[Link] (8 responses)
Despite that advantage, pure message-passing-based concurrency hasn't taken the CS world by storm.
Posted May 8, 2012 18:50 UTC (Tue)
by juliank (guest, #45896)
[Link] (6 responses)
Posted May 8, 2012 19:07 UTC (Tue)
by wahern (subscriber, #37304)
[Link] (2 responses)
Posted May 8, 2012 19:37 UTC (Tue)
by juliank (guest, #45896)
[Link] (1 responses)
Posted May 8, 2012 20:18 UTC (Tue)
by wahern (subscriber, #37304)
[Link]
Limbo succeeded Alef, and Go seems to have succeeded Limbo. But I'll admit this is all just largely opinion.
But more to the point, Plan 9 never touted intraprocess message passing. If you read any of the papers, when they talked about parallelism they spoke about their rfork() system call (which may have inspired Linux' clone syscall; OpenBSD's rfork is clearly derivative of Plan 9). Alef, and later Limbo, was where all the experimentation into messaging passing went, and I think my comparison to Awk v. Unix is apt. To see where I'm coming from, just read their own description and emphasis: http://www.cs.bell-labs.com/sys/doc/9.html
Posted May 9, 2012 16:39 UTC (Wed)
by hanwen (subscriber, #4329)
[Link] (2 responses)
Posted May 9, 2012 18:51 UTC (Wed)
by juliank (guest, #45896)
[Link] (1 responses)
Posted May 11, 2012 13:43 UTC (Fri)
by hanwen (subscriber, #4329)
[Link]
Posted May 8, 2012 20:54 UTC (Tue)
by Cyberax (✭ supporter ✭, #52523)
[Link]
In niche areas Erlang (built on message passing) is quite popular.
Posted May 8, 2012 19:03 UTC (Tue)
by endecotp (guest, #36428)
[Link]
How do you implement your message passing? Most likely it needs some form of locking internally.
I would express it this way: don't try to implement your multi-threaded application using ad-hoc locking / synchronisation. Instead put all of the locking into some concurrency building blocks and restrict your inter-thread communication to only those building blocks. Message passing is one possible set of building blocks, but there are others.
Posted May 8, 2012 19:19 UTC (Tue)
by robert_s (subscriber, #42402)
[Link] (2 responses)
Posted May 9, 2012 2:12 UTC (Wed)
by jamesh (guest, #1159)
[Link] (1 responses)
Things are a bit different if you're talking about cooperative multi-tasking within a single application though: if the application is controlling all the co-routines, then those sort of bugs should be predictable and fixable. Co-routines can greatly simplify some programming tasks: letting you use the stack to manage state, while not having to deal with the complexities of concurrent execution in the same address space.
Posted May 9, 2012 12:37 UTC (Wed)
by geertj (guest, #4116)
[Link]
Exactly - this is the key difference. And it's not like the different threads in a multi-threaded program don't need to cooperate. They can just as easy starve each other if e.g. they do not correctly cooperate in locking.
Posted May 8, 2012 20:11 UTC (Tue)
by valyala (guest, #41196)
[Link] (4 responses)
Posted May 8, 2012 20:31 UTC (Tue)
by wahern (subscriber, #37304)
[Link] (3 responses)
I've been writing event-oriented and thread-oriented C apps for over 13 years. Using makecontext was useful then, but not so much today.
Posted May 9, 2012 2:53 UTC (Wed)
by scottt (guest, #5028)
[Link] (2 responses)
Posted May 9, 2012 11:20 UTC (Wed)
by geertj (guest, #4116)
[Link] (1 responses)
One trick that is sometimes used is sigaltstack() + setjmp(). However i would argue this is actually less portable than writing assembly (the assembly you refer to above is not OS specific, it is only architecture specific and the same function it works on Linux, Mac OSX and Windows).
In the best case, we would get a working and not-deprecated makecontext() function from libc at some point. Also we would need to get an extended longjmp() that allows for code injection in the target co-routine (for propagating exceptions in C++).
Posted May 11, 2012 23:53 UTC (Fri)
by jwakely (subscriber, #60262)
[Link]
Posted May 8, 2012 23:02 UTC (Tue)
by ldo (guest, #40946)
[Link]
Posted May 9, 2012 21:01 UTC (Wed)
by kugel (subscriber, #70540)
[Link]
We actually got rid of this mechanism because is much more performance demanding than real cooperative usermode threads implemented with set/longjmp (pth works like that). Context switch overhead is huge compared to plain longjmp().
One advantage of the pthread-approach is you can temporarily enable preemption during blocking I/O calls so that not the whole program is blocked. Oh, and valgrind/gdb debugability (we actually keep the emulation around for this purpose). But that's about it. For the most part, real cooperative threads perform better. That's our experience.
Coroutines
Coroutines
http://thread.gmane.org/gmane.comp.lib.boost.devel/230507
Coroutines
Coroutines
Coroutines
Coroutines
Coroutines
Coroutines
Coroutines
Coroutines
Coroutines
Coroutines
Coroutines
Coroutines
> passing between threads
Coroutines
Coroutines
Coroutines
Coroutines
Coroutines
A few questions:Re: getcontext/setcontext alternatives
I'm aware that {make,get,set}context() are considered deprecated and were only recently implemented in the glibc ARM port but they're still in use in some reasonably popular apps like the VNC server implementation in qemu etc.
Re: getcontext/setcontext alternatives
> writing per arch "stack switching" code like cgreenlet/greenlet-asm.S?
Re: getcontext/setcontext alternatives
The next logical step is to implement full continuations.
Why Stop At Coroutines?
nPth - The new GNU portable threads library