Home > Back-end >  Why does pthread_join not take a thread pointer?
Why does pthread_join not take a thread pointer?

Time:02-08

Pretty self explanatory question. For example, the header for pthread_create shows it takes a pointer to a thread:

int WINPTHREAD_API pthread_create(pthread_t *th, const pthread_attr_t *attr, void *(* func)(void *), void *arg);

OK, makes sense, you allocate a pthread in memory then pass a pointer to pthread_create so it gets initialized... but now looking at the header for pthread_join:

int WINPTHREAD_API pthread_join(pthread_t t, void **res);

It takes a copy of the pthread_t. I just don't get why it doesn't take a pointer to that already existing thread, rather than copying it and passing it over; it seems like if anything, doing so would cause more problems and more memory use. Am I missing something? I read the manpage, it doesn't seem to offer a reason to this.

CodePudding user response:

It takes a copy of the pthread_t.

Yes.

I just don't get why it doesn't take a pointer to that already existing thread,

pthread_t is a thread identifier. The specs consistently refer to it that way. Copying it does not duplicate the thread itself, nor consume more memory than one pthread_t occupies.

rather than copying it and passing it over; it seems like if anything, doing so would cause more problems and more memory use.

It does not necessarily cause more memory use, as a pthread_t is not necessarily larger than a pointer. It might be a pointer, or an integer. Even if it is a structure, however, there is no reason to think that it so large that passing it by value presents a significant problem, because the specifics are under control of the pthreads implementation. Why would implementers shoot themselves in the foot that way? Note well that passing a structure by value is not inherently less efficient than passing a pointer.

As for problems other than excessive memory use, you would have to be more specific, but I don't see any issues inherent in accessing a copy of a thread identifier directly vs. accessing a common identifier object indirectly, for the purposes of those functions that accept a pthread_t by value.

Am I missing something?

I suspect that your concerns are tied up in a misunderstanding of type pthread_t as somehow carrying data supporting thread operation as opposed to simply identifying a thread.

You may also be supposing that pthreads is a library, with a particular implementation, whereas in fact, it is first and foremost a specification, designed to afford multiple implementations. This is part of the reason for defining abstract data type pthread_t instead of specifying int or struct something * -- implementations can choose what actual type to use.

Perhaps you are also focusing too closely on the API functions. Even if in some particular implementation, passing a pthread_t by value to, say, pthread_join() were less efficient than passing a pointer to one, how much of an impact do you suppose that would actually have? pthread_join() is called infrequently, and only in cases where the caller is prepared to block. What does it matter if argument passing consumes a few more nanoseconds than it might otherwise do?

I read the manpage, it doesn't seem to offer a reason to this.

Few manual pages provide rationale for function design, but I think the most likely explanation is essentially that form follows function. Those functions that receive a pthread_t by value do so because they do not need or want to modify the caller's value. The functions' designs reflect that.

CodePudding user response:

A pthread_t is a small object which identifies a thread. It could be a pointer, integer or perhaps a tiny structure. The pthread_t isn't actually the thread itself any more than a HWND object in Win32 is the window itself.

The pthread_create function returns this identifier via a pointer pointer because it already returns a value of type int for error indication. Other functions take pthread_t by value.

For instance, to compare whether two pthread_t objects refer to the same thread, you should use pthread_equal, which takes two pthread_t parameters. It's possible that all this function does is compare the two values using ==, but doing that directly wouldn't be as portable. It won't even compile if pthread_t happens to be a small structure.

  •  Tags:  
  • Related