Slashdot Mirror


Pthreads vs Win32 threads

An anonymous reader writes "It's interesting when different people have different opinions. While I was searching for something on Intel's website, I came across an article on why Windows threads are better than Posix threads. Curiously, I also came across this article on why Posix Pthreads are better that Win32 threads. The thing is, both of these articles are written by the same author!

So who is right (metaphorically speaking?), or what has changed since the first article was written?"

8 of 385 comments (clear)

  1. Re:Look at the dates, Dude. by AKAImBatman · · Score: 5, Interesting

    I have a feeling that as the author worked more and more with the different threading models, he seems to have a more matured opinion.

    Normally I'd agree with you. But if you read both articles, you realize that his intentions may be a bit less honorable. The Win32 article is the exact same article, but with the conclusions changed. Maturing opinions usually result in some discussion of why one has changed their mind (even if it's only mentioned in passing) and/or a deep explanation of what caused their mind to change. This smells more like an attempt to play both sides.

    Of course, it could be that the author is simply not comfortable with writing. He could be looking to make a quick buck by taking a simple forum post of his and modifying it to reflect his current opinion. It's worth giving him the benefit of the doubt on, but I am certainly suspicious.
  2. there are differences, but not _that_ many by radarsat1 · · Score: 4, Interesting

    The thing is, they are just APIs. They both do just about the same thing. Asking which one is better is a pretty pointless question. I have always thought that the WaitFor* functions in Windows are quite nice, but frankly not that much of an advantage. It's quite rare that you actually need to wait for multiple objects of different types at the same time. Combine that with the fact that its semantics are slightly different for different objects (it destroys a thread, but only unlocks a mutex), and your program is that much more difficult to read. Of course, this is just comparing two APIs, a mostly pointless exercise, and says _nothing_ about implementation, which is quite a bit more important in terms of comparison. For example, Linux has completely changed its pthreads implementation since the switch from 2.4 to 2.6 (from LinuxThreads to NPTL), and programmers get the advantages without needing to change anything. In Windows, of course, we have no (or very little) idea of the implementation, except for what we can infer from the API, and performance tests. A third argument in this little debate could be to argue that one should just stay away from threads, period. I haven't successfully done it myself, since I find the threading paradigm useful, but using processes and non-blocking IO properly, one can avoid threads completely. Of course that's a bit easier to do with some of the Posix functions (eg. socketpair). But doing so will probably result in a more robust piece of software, and which scales better to multiple cores/processors. (Because processes do not share memory, so inter-thread cache misses will be minimized.)

    That said, I find it quite creepy that this guy wrote these two articles with extremely similar wording for his introductions, making the exact opposite points. It is very strange. I wonder what his motivation was.

  3. Re:PThreads is better by fitten · · Score: 3, Interesting

    I've programmed in both and, other than the fact that you can't use sockets in the Wait... APIs (as you mention - but the BSD socket code is layered on top of native Win32, so you'd be passing objects created by two different subsystems to one subsystem's call, which shouldn't be expected to work), the rest of your post is either lack of experience with Win32 threads or subjective preference on your part.

    Personally, I've found situations using each API where the functionality desired was very difficult to replicate in the other API. It usually requires some rethinking, is all. And, last I checked, there were things you could do in either API that weren't easily reproducable in the other API.

    However, both APIs tend to evolve towards each other over time so it becomes less of an issue.

  4. Re:PThreads is better by dmayle · · Score: 4, Interesting

    It's not so cut and dry. I use a library I wrote to abstract away PThreads and Win32 Threads to give me a multi-platform interface, but I would say that each side has their upsides and downsides.

    With pthreads, there's no way to combine socket i/o and thread notification. In Win32, I can have a thread waiting on both a socket and an event at the same time, allowing me to cleanly signal I/O blocked threads. This isn't the case with pthreads.

    However, Win32 REALLY needs a way to handle negative mutexes (ie. taking more than one resource from a mutex at a time). I had to write my own, and it was a serious pain to make sure I didn't have any race conditions. All the articles I've seen on Win32 equivalents had race conditions, and that means that there means that there are probably developers trusting multi-threading primitives that they really shouldn't be./p>

  5. Re:PThreads is better by Twylite · · Score: 4, Interesting

    You are talking mostly bollocks, probably because you don't program using the Windows API

    Anyway, PThreads is better. The reason is that Win32 gives you a fixed set of synchronization primitives. If you can solve your problem with those primitives. they work great. If you can't, you are completely stuck.

    And PThreads also gives you a fixed set of primitives. In some respects they are more powerful, in others they are weaker. This is a bullshit strawman.

    For example, it used to be that a socket handle was not a synchronization object, so you couldn't integrate select() calls with other synchronization primitives.

    WTF?

    1. select() has nothing to do with synchronization. Although it does have something to do with scheduling.
    2. select() can't wait on "synchronization primitives" under *nix. Really. Try man select . It works with FDs, only.
    3. select() is not a core function of the Windows API. It is part of Winsock, which uses lower level scheduling primitives.
    4. Finally, if you want to do asynchronous development with Windows you use Async IO, not select. Async IO is built on top of Events, which are synchronization primitives.

    That brings me to the next point: in Unix there is no wait to wait on multiple synchronization primitives (as opposed to FDs) at once, and only a few primitives support a timed wait. In Windows you have WaitForMultipleObjectsEx. Look it up.

    Let me be clear on the difference: in Windows the scheduler API for waiting on IO and synchronization primitives is fully integrated - you can wait on any combination of IO and sync objects in the same Wait call. You must of course be using Windows Async IO which uses Events rather than FDs as the waitable object. Under *nix you can wait for multiple condition variables, or multiple file descriptors, or a single mutex / thread / process. There is no way to link an FD to a condition variable.

    PThreads gives you condition variables. They are harder to program, but once you understand them, you can use them to synchronize on absolutely anything. You aren't dependent on the OS to have foreseen your special needs and provided special synchronization primitives to meet them.

    In Windows you have Mutexes, Events and Semaphores. Events alone are sufficient to provide almost identical functionality to condition variables. You may have missed that memo.

    I say "almost identical" because the underlying scheduler behaviour is slightly different, which makes it very difficult to perfectly emulate Pthreads on Win32. Read Strategies for Implementing POSIX Condition Variables on Win32.

    If you really want the Win32 model, it is easy enough to build it on top of PThreads, but there is no way to build PThreads on top of Win32.

    Cough. Bullshit. Cough. Read Porting of Win32 API WaitFor to Solaris Platform to get a clue. It is possible to build Pthreads on top of Win32, and vice versa. Neither emulation is particularly efficient though.

    The complaint about lost signals in PThreads means that the author is using them incorrectly.

    The complaint about weakness in the Win32 scheduling API means that the author is using it incorrectly.

    --
    i-name =twylite [http://public.xdi.org/=twylite], see idcommons.net
  6. Re:quothe the poster by Courageous · · Score: 4, Interesting

    Nobody program for Windows because he likes to program for Windows...

    To the contrary. I work on Linux systems at work, and play on Windows, using .NET (C#) at home, for fun. .NET is a genuine pleasure to work with: a better java than java, I say. It may be an asset of the evil empire, and it may not be multiplatform, but I find those to be its only weaknesses.

    C//

  7. Re:Eeew, threads. by Mysticalfruit · · Score: 5, Interesting

    A while back I had to write a server that would recieve concurrent network connections from different clients and then get some data from those clients and do some processing and then interact with a database, then when it's done the fork exits.

    I ended up writing the whole thing using forks and no pthreads. My code was then subjected to a code review and one of the questions that came up in the review meeting was why I used fork and didn't do the implementation in pthreads. My arguement was one of complexity. I was challenged with the "fork is old technology, you should have used pthreads" and my response was "My implementation is easy to understand, oh and by the way, it works!"

    Needless to say, my code has been in production for about a year and a half with no issues. I'm sure someone smarter than me could have wrote the whole using pthreads, but I'm just not sure what it would have gained them other than a slightly smaller memory footprint but at the price of increased complexity.

    --
    Yes Francis, the world has gone crazy.
  8. Re:Eeew, threads. by EvanED · · Score: 3, Interesting

    Maybe it originated like that, but the fork/exec model of starting a new process has another really big benefit as compared to, say, Windows's CreateProcesses, which is that it's easier to control the execution environment of the child process.

    Running as root and want to start the process with lower privileges? Do fork - setuid - exec. Want to open pipes to the child? Do pipe - fork - a couple calls in the child to connect the pipes to stdin/out - exec.

    By contrast, Windows has to encapsulate anything you want to be able to do to set up the child's environment in the CreateProcess call. That's why it takes 9 arguments, one of which is a flags argument where there are 15 flags, and one of which is a pointer to a struct with 17 fields (one of which takes another 9 flags).