Slashdot Log In
Pthreads vs Win32 threads
Posted by
Hemos
on Mon Feb 26, 2007 10:00 AM
from the different-situations,-different-needs dept.
from the different-situations,-different-needs dept.
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?"
So who is right (metaphorically speaking?), or what has changed since the first article was written?"
This discussion has been archived.
No new comments can be posted.
The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
quothe the poster (Score:5, Insightful)
Vista's release and a massive advertising campaign/increase in revinue for microsoft partners?
Re:quothe the poster-What Has Changed (Score:5, Insightful)
What has likely changed is were the paycheck came from this week.
Parent
Nothing has changed (Score:5, Informative)
Although there are three year between the articles and people change, this looks to me like someone trying to write different articles from different viewpoints rather than proving that one is best. If he really had changed his mind, maybe he would have said so and referenced his previous article rather than copying it?
Parent
Re:quothe the poster (Score:5, Funny)
Parent
Re:quothe the poster (Score:5, Funny)
A)to To other side. get the
Q)Why did the multithreaded chicken cross the road?
A)other to side. To the get
Parent
Re:quothe the poster (Score:5, Funny)
A) They came at the same time, but the multithreaded chicken terminated first.
Q) Which came first, the multithreaded chicken or the multithreaded egg?
A) Neither; mt egg could not acquire chicken-lock from mt chicken. mt chicken could not acquire egg-lock from mt egg.
Q) Which came first, the multithreaded chicken or the multithreaded egg?
A) Multithreaded egg, but it overwrote its DNA while still in use and became mt turkey.
Parent
Re:quothe the poster (Score:4, Informative)
I can only hope that's funny.
This is [censored] reality. Nobody program for Windows because he likes to program for Windows: people do that mainly for money. "Work" they say.
Whatever you appear to like in competing implementations is irrelevant: M$ and corporate decision makers leaves you no choice.
And there are really only two choices: (1) you go insane and start loving whatever management tells you to love or (2) you search for another job. Since the guy is with Intel, he's likely to have good payroll and option (2) doesn't ring any bells.
[ I hope you have noticed that "I love POSIX" post is from year 2003 - and "I love Windows" from 2006. But honestly it all looks more like joke. ]
I'd say from personal experience, that threading in Windows is total mess. POSIX threads might look limiting - but on other side you need to resort to threads in *nix ... well you do not have to resort to threads all. It is your own programmer's choosing: to use threads or to use state machines and async I/O. Under Windows bugs plagued/plague/will plague async I/O and programmers have no choice other then to use threads for sockets and file I/O. So under Windows you use threads for everything (except GUI which is restricted to "main thread"), while in *nix it is norm to see threads only in applications which want to take advantage of multi-processor systems for heavy computational tasks: math, code cracking, video encoding, etc. Heavy I/O tasks in *nix are all single threaded: Apache, Squid, MySQL, PostgreSQL, postfix/sendmail/exim, etc. (Though most now support optional multi-threading too - for really busy servers.)
Parent
Re:quothe the poster (Score:5, Funny)
Parent
Re:quothe the poster (Score:5, Interesting)
To the contrary. I work on Linux systems at work, and play on Windows, using
C//
Parent
Re:quothe the poster (Score:4, Insightful)
Bullshit. I develop full-time in J2SE/J2EE and now C# (.NET 2.0/3.0) as well. If you are just some beginner/non-developer, writing slightly more complicated Hello World applications, then you are not going to see any real difference between Java or
The features and functionality available in Java 6 are astounding and are aimed squarely at making J2SE on the desktop, making J2ME ubiquitous in mobile devices, as well as securely putting J2EE years ahead of it competition. Java 7 is looking to be even more exciting.
For everyone whose last memory of Java is 10 years ago, you need to look at it again. Aside from basic single platform desktop applications,
All of the enterprise
Parent
Re:quothe the poster (Score:5, Informative)
Initial (2003) article: And in the later article: It's not plagiarism because he copied from himself and just added a few edits, but c'mon... how lazy of a shill can you be?
Parent
Re:quothe the poster (Score:4, Funny)
It's GNU/Linsux you bastards! When are you going to get it right! Arghh!
Parent
$Money$ (Score:5, Insightful)
Who was paying for it.
Pthreads = Win32 threads? (Score:5, Funny)
Re:Pthreads = Win32 threads? (Score:5, Funny)
Although, it may be true that Win32 threads = Pthreads (which may account for the improvement)
Parent
Look at the dates, Dude. (Score:3, Insightful)
Re:Look at the dates, Dude. (Score:5, Informative)
Parent
Re:Look at the dates, Dude. (Score:5, Interesting)
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.
Parent
Re:Look at the dates, Dude. (Score:5, Insightful)
The question is, did the author really change his mind, or is he writing the conclusions that he knows will net him an income? If it's the former, he really should have expanded his article to prevent this sort of issue. If it's the latter, then the author is untrustworthy and should no longer be paid to provide his opinion in any professionally written form.
Microsoft never enters into the equation here, save for the fact that some entities may have a monetary interest in promoting Microsoft Windows -OR- Linux. (There's money in both directions.) That being said, it is sad that this issue may never have come up if the order of the articles was reversed. Slashdot is very pro-Linux (something which I am ambivalent about), meaning that it would have likely been seen as a win rather than the questionable journalism it is.
Parent
Re:Look at the dates, Dude. (Score:4, Insightful)
I certainly hope that someone who first claims that "Separate data types" make Pthreads superior to Win32 threads and then turns right around and claims that they in fact make Pthreads inferior to Win32 threads gets viewed with a certain amount of suspicion, on Slashdot as well as everywhere else.
Parent
Re:And so the point becomes... (Score:5, Funny)
You know, I said this very same thing back in the 70s. However, my buddy with the bell bottoms and KISS shirt got more play than I ever did with my adidas shorts and Vader cape.
Parent
From the obvious dept (Score:5, Funny)
Re:From the obvious dept (Score:5, Funny)
Parent
Eeew, threads. (Score:3, Informative)
Threads have all sorts of nasty issues and pitfalls on any platform. Meanwhile, fork() is beautifully simple, and fork + socketpair lacks pretty much all of them. The speed may be a bit lower, but there's the great benefit of simpler and much safer code.
Re:Eeew, threads. (Score:4, Informative)
I don't know why the Windows equivalent of fork() is slower than the Unix fork(). Perhaps it is a historical thing. Unix programs often use fork() - shell scripts use it all the time (this is one reason why a Python or Perl script is often faster). I'm just guessing now, but perhaps Unix fork() is efficient because it is frequently used and has therefore been optimised in various ways (e.g. memory is only copied if there is a write on Linux). Whereas on Windows, those optimisations are not necessary.
Parent
Re:Eeew, threads. (Score:5, Informative)
I already got modded down for mentioning it elsethread (not sure why), but Windows does have ZwCreateProcess and NtCreateProcess. Both of those will do a copy-on-write fork() style process creation if you pass them a NULL SectionHandle--it is much more efficient than the normal CreateProcessEx and is the way to go for doing heavy multiprocess stuff on Win32.
see, e.g., http://www.osronline.com/showThread.cfm?link=3591
Parent
Re:Eeew, threads. (Score:5, Interesting)
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.
Parent
Re:Eeew, threads. (Score:4, Informative)
Parent
And memory footprint is a red herring. (Score:4, Insightful)
Parent
Re:Eeew, threads. (Score:4, Interesting)
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).
Parent
Re:Eeew, threads. (Score:5, Insightful)
You have to consider the task you're working on before you decide whether you want to go with fork/exec or multiple threads.
A sibling post mentioned the cost of creating new processes on windows, and that's definitely something to consider: it's quite expensive to do so on windows.
However, the more important question is the problem you're working on solving.
If you're working on a task that allows each drone to work without communicating with any of the other drones, then fork/exec is a possible candidate. If you're working on an application where you require even a minimal amount of synchronization between different drones, fork/exec is a huge, huge pain in the ass.
An example of a good fork/exec app: webserver. One process deals with hearing the incoming connection, spawns off a new process to actually handle an individual connection. As a bonus, a single bad client connection will most likely NOT kill the whole webserver. (A malicious client will kill the process they've connected to, but probably none of the other processes, unless they manage to hang a database, etc).
An example of a good multithreaded app: anything that plays lots of sounds (for a specific example, a game). There's lots of synchronization that has to go on here: threads have to be started (or more likely pulled from a pool) to play a sound, the threads playing the sound have to check back periodically to see if they should stop playing (or need to adjust their volume or other processing effects), they need to notify the originating thread when they have completed, etc. No one in their right mind would use fork/exec for this. Besides the high overhead of the process spawn on windows, you would need a process for each of the sounds playing, and you would need to use the OS interprocess communication apis to synchronize between the different processes (shared memory, global mutexes, or file pipes). Note that file pipes aren't sufficient for synchronization, so you'd still have to use OS mutexes to sync on.
Yup.
Parent
win32 has 1 thing i want pthreads to have (Score:3, Informative)
pthread_join_with_timeout() the equivilent of the win32 WaitForSingleObject
often i set a flag for a thread to end and it might have already been completed. i want to be able to join immediately if it's already completed and if it isn't process some other event and try to join again.
i can program around this however it would be extremely nice addition to pthreads.
Re:win32 has 1 thing i want pthreads to have (Score:5, Informative)
I'm not an expert on pthreads by any means, but I think what you're looking for is pthread_cond_timedwait().
Parent
Re:win32 has 1 thing i want pthreads to have (Score:5, Informative)
Sure, you could implement something like pthread_join_with_timeout() using a conditional inside the thread. But you'd need to do that manually, as pthreads doesn't provide a primitive for that particular use-case AFAIK.
Parent
PThreads is better (Score:5, Informative)
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.
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. Maybe that's been fixed, but if it isn't sockets, it will be something else.
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.
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.
The complaint about lost signals in PThreads means that the author is using them incorrectly.
Re:PThreads is better (Score:5, Informative)
Parent
Re: (Score:3, Interesting)
Not strictly true. It is possible to build condition variables for Windows (Windows has Semaphores after all, which can be used to make just about anything), but the Windows threading model makes doing so far from easy. Please note that I'm not defending WinThreads, however, so much as clarifying this particular issue.
Re:PThreads is better (Score:5, Informative)
Vista comes with APIs for condition variables and reader-writer locks so you don't have to spend 15 minutes writing your own.
Parent
Re:PThreads is better (Score:5, Insightful)
Well, fifteen minutes writing, plus ten years of programming experience to be sure that you aren't going to create a deadlock in some obscure circumstance.
Parent
Re:PThreads is better (Score:5, 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>
Parent
Re:PThreads is better (Score:5, Interesting)
You are talking mostly bollocks, probably because you don't program using the Windows API
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.
WTF?
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 [microsoft.com]. 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.
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 [wustl.edu].
Cough. Bullshit. Cough. Read Porting of Win32 API WaitFor to Solaris Platform [sun.com] 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 weakness in the Win32 scheduling API means that the author is using it incorrectly.
Parent
Re:PThreads is better (Score:4, Insightful)
From the great grandparent:
From me (the grandparent):
It is not easy to build the Win32 model on Pthreads. The WaitForMultipleObjects emulation is a complete hack that pretty much re-implements the Win32 scheduler in userland. Even then it doesn't support a number of synchronization objects that Win32 can (e.g. threads, so that you can wait for thread termination). And it won't work properly unless the underlying *nix scheduler displays round-robin characteristics (anything with historical scheduling will cause a Producer-Consumer arrangement that works perfectly on Win32 to display massive latency on *nix).
The Solaris WaitFor described in that document works only with Event objects. You can't wait on anything other than events like you can in Win32, and you can't link Solaris file IO states (i.e. readable or writable) to those emulated events.
So you can't construct an instruction like "Wait for socket X to be readable OR event QUIT to be signalled", which is quite possible in Windows. In fact you can't do that at all on any *nix system that I am aware of (not even with kqueue or dev/poll to my knowledge). Instead you loop checking QUIT then doing a select()/poll() X with a timeout.
Parent
It's quite simple, really (Score:4, Funny)
there are differences, but not _that_ many (Score:5, Interesting)
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.
Is this a joke ? (Score:4, Informative)
First of all on it's own terms the story makes no sense, the anonymous coward starts off by saying it's interesting when people disagree. He then links to two articles which, as he points out, are written by the same person and then asks who is right. He has just pointed out the opinions are both from the same person and he wants to know who is right, this is just moronic.
Secondly although I know nothing about PThreads or Win threads I can see that both those articles are largely the same with just the terms PThreads and Win threads switched so in one article he is claiming an advantage for one based on what he has stated as the advantages of the other in his other article.
Why is this on the front page, why was the submission accepted in the first place when it's complete nonsense and the most recent post by the author of both articles was in 2006.
A better Win32/Linux thread article (Score:5, Informative)
http://www-128.ibm.com/developerworks/linux/libra
Enjoy,
wdiff output (Score:4, Informative)
Clay Breshears
[-2006-10-19-]
{+2003-05-13+}
I've used both POSIX threads (Pthreads) and [-Win32-] {+Windows+} threads [-APIs-] {+APIs,+} and I believe that [-Pthreads-] {+Windows+} has the better programming model of the two. While each threading method can create threads, destroy threads, and coordinate interactions between threads, the reason I make this claim is the simplicity of use and elegance of design of [-Pthreads.-] {+the Windows threads API. This is all from the perspective of multithreaded code developers or maintainers.+} Let me illustrate with a few examples.
[-Separate-] {+Simplicity of+} data types. In Pthreads, each object has its own data type [-while-] {+(pthread_t, pthread_mutex_t, pthread_cond_t, etc.) while,+} in [-Win32 threads-] {+Windows threads,+} there is [-a mix of handles and separate types.-] {+pretty much just the one type: HANDLE.+} For Pthreads this means different functions are used for working with each object type. Reading and understanding Pthreads code written by someone else [-is straightforward-] {+can be straightforward. However, this does mean that the programmer must know the number, order,+} and [-less apt to lead to confusion.-] {+type of parameters for all the different functions.+} On the other hand, because of the use of the same type for different objects, [-when-] {+there is+} a [-Win32 program uses WaitForSingleObject, it may not-] {+Create* function for each different object and a corresponding Release* function for most.
Perhaps the biggest advantage of a single object data type is that there is only the one function needed to make a thread block while waiting for an object: WaitForSingleObject. Thus, only one set of parameters needs to+} be {+known regardless of whether the code is waiting on a thread, a mutex, a semaphore, or an event. The related function, WaitForMultipleObjects, is just as simple to use and easily overcomes the problem of needing to wait for multiple thread terminations one function call at a time (pthread_join) that Pthreads requires. While some may say that using a single data type for many different objects can lead to confusion when used in WaitFor* calls, programmers should set the name of the handle such that it is+} readily apparent [-if-] {+whether+} the code is expecting a thread termination, an event to be signaled, or a mutex to be released. [-This also illustrates my next point.
Unambiguous-] {+WaitForMultipleObjects+} functionality. [-I've-] {+Besides being able to block a thread waiting for multiple thread terminations in a single call, the programmer can+} actually [-seen Win32-] {+wait for any out of a set of threads to terminate. That is, even when only one thread has completed, the WaitForMultipleObjects function can be set to return and indicate which thread triggered the return. If there is specific "clean up" processing that depends on the identity of the thread that finished, this can be done before returning to wait on the remaining threads. This clean up processing will be done in the most efficient order possible, soon after each thread terminates, no matter in what order this happens. Pthreads can perform similar post-processing, but will need to wait for the threads to terminate is some fixed order. So, even if the last thread finishes first, it must wait for all the post-processing of the previous threads to be completed.
Because different objects all use the HANDLE type, a call to WaitForMultipleObjects can be set to wait for any combination of threads, mutexes, semaphores, and/or events. This feature can give the programmer a flexibility that cannot be easily (if at all) duplicated in Pthreads. As an example, I've written Windows+} code that used an array to hold both thread and [-mutex handles, then wait on those-] {+event+} handles {+to support a threaded search through data. The ideas was to signal the blocking thread if the item being looked for was found+} and [-execute differen
Submitter is nuts (Score:4, Funny)
We have always been at war with Pthreads. We have never been at war with Windows threads.
The submitter is clearly nuts. Everyone knows that we have always been at war with Windows threads. Anyone who suggests we're at war with Pthreads is insane.
He responded. (Score:4, Informative)
Re:Yes, the real world is a complicated place. (Score:5, Insightful)
From the first one:
Parent