Discussion:
Negative numbers for thread ID - why ?
(too old to reply)
m***@gmail.com
2007-01-17 15:58:55 UTC
Permalink
Hello,

I am running FC6 machine (i386 based).
I am trying the follwing:

create a thread with pthread_create().
in the thread function, I have:
printf("tid in thread_func=%d\n",(int)pthread_self());

I get negative number for the thread id, for example:

tid in thread2_func=-1218974832

Why is it so ?
I saw in some places usage of this method (pthread_self()),but
it returned non negative numbers.

Any ideas?
Regards,
Mark
Lew Pitcher
2007-01-17 16:18:56 UTC
Permalink
Post by m***@gmail.com
Hello,
I am running FC6 machine (i386 based).
create a thread with pthread_create().
printf("tid in thread_func=%d\n",(int)pthread_self());
tid in thread2_func=-1218974832
Why is it so ?
Why? Because you made it so.
Remember, the "%d" printf format string tells printf to interpret the
incoming value as a *signed* integer. The data you got back from
pthread_self(), when cast to an integer value and interpreted as a
signed integer, had a value of -1218974832. Had you told printf() to
print it as "%u", you would have seen a different printed value because
you would have told printf() to interpret the number as an unsigned
integer.
Post by m***@gmail.com
I saw in some places usage of this method (pthread_self()),but
it returned non negative numbers.
This usage will print non-negative values for pthread_self() values
that are smaller than INT_MAX + 1
Spoon
2007-01-17 16:36:12 UTC
Permalink
Post by m***@gmail.com
I am running FC6 machine (i386 based).
create a thread with pthread_create().
printf("tid in thread_func=%d\n",(int)pthread_self());
pthread_self() returns a pthread_t
http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_self.html

On my platform pthread_t is an unsigned long int.
David Schwartz
2007-01-17 18:22:49 UTC
Permalink
Post by m***@gmail.com
create a thread with pthread_create().
printf("tid in thread_func=%d\n",(int)pthread_self());
tid in thread2_func=-1218974832
Why is it so ?
I saw in some places usage of this method (pthread_self()),but
it returned non negative numbers.
This code is fundamentally broken. You cannot cast the return value of
'pthread_self' to an integer and expect it to give you anything
meaningful. If you want to assign positive integers to threads, you
have to do it.

DS
David T. Ashley
2007-01-17 21:50:22 UTC
Permalink
Post by m***@gmail.com
Hello,
I am running FC6 machine (i386 based).
create a thread with pthread_create().
printf("tid in thread_func=%d\n",(int)pthread_self());
tid in thread2_func=-1218974832
Why is it so ?
I saw in some places usage of this method (pthread_self()),but
it returned non negative numbers.
Any ideas?
Surprisingly, somebody posted the exact same type of question on comp.lang.c
within the last 72 hours or so. I'll paste in the text of my reply below.

----BEGIN PASTED POST FROM COMP.LANG.C
Post by m***@gmail.com
Hi,
I was writing a testing program to test the ranges of char, short, int and
long variables on my computer, both signed and unsigned.
Everything was fine except for unsigned int and unsigned long. I got
unsigned int: 0 to 65535
unsigned long: 0 to 4294967295
What might be wrong here? Please help.
Assuming a standard 2's complement machine (just about all of them nowadays,
I think), the reason you got -1 is that the bit pattern of all 1's in an
integer data type corresponds to:

a)The largest possible positive value, if the data is interpreted as an
unsigned type.


b)-1, if the value is interpreted as a signed type.


As other posters pointed out, the problem was the format specifier. The
format specifier caused interpretation as a signed type.


An integer in memory is just a collection of 0's and 1's. It can be either
unsigned or signed. It is all in how you interpret it.


2's complement has historically been used in computers because the same
addition and subtraction instructions give correct results for both unsigned
and signed interpretations. However, a little extra digital logic and a
couple of extra flags are required in the processor for correct branches and
so on.


The smallest practical example is 3 bits. Here are the values when
interpreted as unsigned and signed.


Bit Pattern Unsigned Signed


000 0 0
001 1 1
010 2 2
011 3 3
100 4 -4
101 5 -3
110 6 -2
111 7 -1


Notice that if N is the number of bits, the largest value corresponds to
2^N-1 as an unsigned or -1 as a signed.


This is all explained (I hope) here:


http://en.wikipedia.org/wiki/Twos_complement


One other thing you might notice is that the representations correspond to
the same values up until the sign bit is set. It is a not-uncommon problem
in 'C' to introduce a bug that only becomes apparent at large data values
because one somehow casts an unsigned to a signed. Everything works great.
Until 2^(N-1). Then all hell breaks loose.


-----END PASTED POST
--
David T. Ashley (***@e3ft.com)
http://www.e3ft.com (Consulting Home Page)
http://www.dtashley.com (Personal Home Page)
http://gpl.e3ft.com (GPL Publications and Projects)
l***@gmx.net
2007-01-17 23:46:54 UTC
Permalink
Hi Mark,
Post by m***@gmail.com
I am running FC6 machine (i386 based).
create a thread with pthread_create().
printf("tid in thread_func=%d\n",(int)pthread_self());
tid in thread2_func=-1218974832
Why is it so ?
I saw in some places usage of this method (pthread_self()),but
it returned non negative numbers.
Any ideas?
As stated by POSIX, pthread_t is an opaque type. The internal
representation should not matter to you. That's why there is function
like /pthread_equal()/ to compare two thread IDs BTW.

Now, it is not uncommon to print out the thread id of a given thread,
for debugging purpose for instance. If you want to do so, you must then
know how the underlying Pthreads implementation represents the thread
id. For your FC6, it's actually a pointer, so you should be using the
"%p" formater. On former Linux system with LinuxThreads, things would
have been different, because the thread id was actually an index in a
table (which may explain the "%d").

As mentioned by David already, if you undertake this path, you should
remind yourself that the resulting program, besides of being not POSIX
conform, may not be portable.

HTH,
Loic.
Keith Thompson
2007-01-18 04:19:44 UTC
Permalink
loic-***@gmx.net writes:
[...]
Post by l***@gmx.net
As stated by POSIX, pthread_t is an opaque type. The internal
representation should not matter to you. That's why there is function
like /pthread_equal()/ to compare two thread IDs BTW.
Now, it is not uncommon to print out the thread id of a given thread,
for debugging purpose for instance. If you want to do so, you must then
know how the underlying Pthreads implementation represents the thread
id. For your FC6, it's actually a pointer, so you should be using the
"%p" formater. On former Linux system with LinuxThreads, things would
have been different, because the thread id was actually an index in a
table (which may explain the "%d").
On *my* FC6 system, pthread_t is a typedef for unsigned long int:

% cat /etc/fedora-release
Fedora Core release 6 (Zod)
% grep pthread_t /usr/include/bits/pthreadtypes.h
typedef unsigned long int pthread_t;

It's possible, I suppose, that the unsigned long int is used to store
a pointer value.

If you want to print a pthread_t value, you can either dive into your
system's headers and use a format appropriate to the way the type is
defined (and give up portability), or print the bytes making up the
representation of the pthread_t value, for example in hex.
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
l***@gmx.net
2007-01-18 11:57:13 UTC
Permalink
Hi Keith,
Post by Keith Thompson
% cat /etc/fedora-release
Fedora Core release 6 (Zod)
% grep pthread_t /usr/include/bits/pthreadtypes.h
typedef unsigned long int pthread_t;
It's possible, I suppose, that the unsigned long int is used to store
a pointer value.
technically speaking, the thread id is a pointer to a structure holding
the relevant thread information. It is indeed casted to an unsigned
long int.

Cheers,
Loic.

Loading...