Follow Slashdot blog updates by subscribing to our blog RSS feed

 



Forgot your password?
typodupeerror
×

Pthreads vs Win32 threads 385

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?"
This discussion has been archived. No new comments can be posted.

Pthreads vs Win32 threads

Comments Filter:
  • Eeew, threads. (Score:3, Informative)

    by vadim_t ( 324782 ) on Monday February 26, 2007 @11:10AM (#18152976) Homepage
    Here's the one thing Windows needs: fork()

    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.
  • by musikit ( 716987 ) on Monday February 26, 2007 @11:11AM (#18153006)
    i have had to do a lot of porting from win32 to linux/bsd/mac lately and maybe i just cant find it in the documentation anywhere but 1 function i would really appreciate the pthread team adding is

    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.
  • by Anonymous Coward on Monday February 26, 2007 @11:11AM (#18153010)
    Except that the 2006 entry is essentially a structural copy of the 2003 entry, just with some wording changes. He even uses the same arguments against PThreads in the second entry that he used to support it in the first. Weird...
  • PThreads is better (Score:5, Informative)

    by swm ( 171547 ) <swmcd@world.std.com> on Monday February 26, 2007 @11:19AM (#18153086) Homepage
    The articles read like one of those English assignments where you have to pick an issue and then write two essays, one supporting each side. Probably the author wrote them to generate traffic to his websites, or maybe for freelance fees.

    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.
  • Both and Neither (Score:2, Informative)

    by FellowConspirator ( 882908 ) on Monday February 26, 2007 @11:21AM (#18153122)
    It's not that difficult. POSIX' value is in its portability. Win32's value is in the fact that it's the native model.

    Generally speaking, the native model will always offer superior performance and a superset of the features of POSIX threads. Be that Win32, Solaris, Linux, or what have you -- it's a good rule of thumb that the native threading model and API performs better and is more flexible.

    That said, the difference is generally small enough that it's eclipsed by the portability feature if portability will ever be a concern. The fact that the programmer can learn a single threading API and use it anywhere means more flexibility in development and finding developers, and generally higher code quality (since people that have a skill focus on multi-threaded programming are almost assuredly well-versed in the POSIX API).
  • Is this a joke ? (Score:4, Informative)

    by CmdrGravy ( 645153 ) on Monday February 26, 2007 @11:31AM (#18153222) Homepage
    Is this some kind of weird joke ?

    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.
  • Re:Eeew, threads. (Score:4, Informative)

    by Cheesey ( 70139 ) on Monday February 26, 2007 @11:32AM (#18153234)
    On Windows, there is a much higher penalty associated with spawning a child process than on Unix. This makes using threads much more attractive - they are faster.

    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.
  • by leuk_he ( 194174 ) on Monday February 26, 2007 @11:33AM (#18153252) Homepage Journal
    there is a pthreads [sourceware.org] implementation build on top if win32. I am not saying it is efficient, but it does the job.
  • by tjw ( 27390 ) on Monday February 26, 2007 @11:35AM (#18153280) Homepage

    I'm not an expert on pthreads by any means, but I think what you're looking for is pthread_cond_timedwait().
  • by PhrostyMcByte ( 589271 ) <phrosty@gmail.com> on Monday February 26, 2007 @11:36AM (#18153294) Homepage
    You're in luck-

    Vista comes with APIs for condition variables and reader-writer locks so you don't have to spend 15 minutes writing your own.
  • by NullProg ( 70833 ) on Monday February 26, 2007 @11:47AM (#18153440) Homepage Journal
    It sounds like the developer from Intel needs to ask IBM:

    http://www-128.ibm.com/developerworks/linux/librar y/l-ipc2lin1.html [ibm.com]

    Enjoy,
  • by dmayle ( 200765 ) on Monday February 26, 2007 @12:44PM (#18154238) Homepage Journal

    As my comment is mounting in score, I just realized that I said negative mutexes when I meant negative semaphores. Of course you can't have a negative mutex, a mutex is just for mutual exclusion. It's a semaphore that has a count associated with it.

    Sorry for the typo...

  • Re:quothe the poster (Score:4, Informative)

    by ThePhilips ( 752041 ) on Monday February 26, 2007 @01:00PM (#18154506) Homepage Journal

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

  • by dominator ( 61418 ) on Monday February 26, 2007 @01:05PM (#18154616) Homepage
    pthread_cond_timedwait() waits on a condition variable, which basically signals that a mutex has been released. Win32 calls these things "events". It is not the same thing as joining on a thread. Joining a thread means "I'm waiting for this thread to exit, so that I can capture its return value."

    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.
  • wdiff output (Score:4, Informative)

    by cortana ( 588495 ) <sam@robots[ ]g.uk ['.or' in gap]> on Monday February 26, 2007 @01:27PM (#18155010) Homepage
    Why [-Pthreads-] {+Windows Threads+} are better than [-Win32 threads-] {+POSIX Threads+}
    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
  • Re:quothe the poster (Score:5, Informative)

    by PitaBred ( 632671 ) <slashdot&pitabred,dyndns,org> on Monday February 26, 2007 @01:37PM (#18155176) Homepage
    Did you notice the other similarities?

    Initial (2003) article:

    I've used both POSIX threads (Pthreads) and Win32 threads APIs and I believe that Pthreads 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. Let me illustrate with a few examples.
    And in the later article:

    I've used both POSIX threads (Pthreads) and Windows threads APIs, and I believe that 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 the Windows threads API. This is all from the perspective of multithreaded code developers or maintainers. Let me illustrate with a few examples.
    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?
  • by boa ( 96754 ) on Monday February 26, 2007 @01:52PM (#18155440)
    >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.

    A quick look in pthread.h tells me that there's one function named pthread_timedjoin_np. The function seems to be a GNU extension and the _np suffix is short for not portable. It probably does that the OP wants, but may not be portable enough for his needs.

    HTH
    boa
     
  • by gooser23 ( 113782 ) on Monday February 26, 2007 @02:18PM (#18155868)

    You may not be able to use sockets directly with WaitFor[Single|Multiple]Objects(s), but you can attach an event to a socket (using WSAEventSelect IIRC) and wait on that, along with other things (which effectively gives you BSD's select() for Windows' file handles.

    As far as the discussion on concurrent programming goes, I'm surprised no one has yet mentioned boost.threads [boost.org].

  • Re:Eeew, threads. (Score:3, Informative)

    by pthisis ( 27352 ) on Monday February 26, 2007 @03:00PM (#18156594) Homepage Journal
    Windows does have a copy-on-write process creation mechanism--use ZwCreateProcess or NtCreateProcess with a NULL SectionHandle. It wasn't in Win98 and earlier, and it's poorly documented, which means a lot of Windows programmers don't use it and threads get massively overused.

    But threads are rarely the right choice; OS developers spent years implementing protected memory for good reasons, and throwing it out even within the bounds of one process is rarely beneficial. If you need to share a ton of complex data structures that can't easily be allocated in shared memory, then threads are worthy of consideration; in practically every other case, multiple process solutions will wind up being easier to implement and maintain, and more stable.

    Threads look seductively easy at the outset, but you actually have to do a lot of bean counting to get things right; with multiple processes, you have to explicitly set up IPC which makes it _look_ more complex but in reality makes it very clear what the shared resources are. Finding any synchronization problems usually winds up being a lot easier in multiple process systems, and there are the obvious stability and security benefits.

    And depending on the task, multiple process solutions may actually be faster since when 2 process are running on seperate CPUs there's no need to worry about cache coherency, etc between them unless they're actually hitting shared resources.

    But the performance differences tend to be negligible in practice for many applications; benchmark and see before assuming.
  • Re:quothe the poster (Score:2, Informative)

    by PitaBred ( 632671 ) <slashdot&pitabred,dyndns,org> on Monday February 26, 2007 @03:21PM (#18156984) Homepage
    ...civil disobedience is going against laws. I am fairly certain there was no governmental entity that told him to change his viewpoint on Windows threading.
  • Re:Eeew, threads. (Score:4, Informative)

    by Kashif Shaikh ( 575991 ) on Monday February 26, 2007 @03:29PM (#18157108)
    You had no issues because a) performance was good enough and b) the rate of incoming client requests was relatively small compared to a loaded webserver. Now if you had thousands of client requests-per-second, the fork will show why-you-should-not-use-it-in-such-situations. In such cases you can use a pool of forked processes or simply write the whole damn thing using threads. For example, apache gives you the ability to change 'worker' modules...and you can experiment with that to get an idea of all these request processors. btw, threads don't complicate your code as long as you minimize data-sharing between threads and write the thread the same way as you were writing a forked process, except that you put all global variables within the thread's local data area. Kashif
  • Re:Eeew, threads. (Score:5, Informative)

    by pthisis ( 27352 ) on Monday February 26, 2007 @07:05PM (#18160094) Homepage Journal

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


    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=35916 [osronline.com]
  • Nothing has changed (Score:5, Informative)

    by einhverfr ( 238914 ) <chris...travers@@@gmail...com> on Monday February 26, 2007 @10:24PM (#18162282) Homepage Journal
    Read the two articles closely, and side by side. What you will see is that both articles have an identical structure and make simply the opposite cases. The opening is almost verbatim between the two articles, for example.

    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?
  • by mattis_f ( 517228 ) on Monday February 26, 2007 @10:45PM (#18162442)
    I was also fascinated by that ... but the articles actually diverge a bit later. The difference seems to be WaitForSingleObject in Win32 (in the older article, apparently it's not a good thing) which has been replaced by WaitForMultipleObject in the newer one (according to the author, a good thing).

The use of money is all the advantage there is to having money. -- B. Franklin

Working...