How does POSIX Threads work in linux? - c

I thought pthread uses clone to spawn one new thread in linux. But if so, all of the threads should have their seperate pid. Otherwise, if they have the same pid, the global variables in the libc seem to be shared. However, as I ran the following program, I got the same pid but the different address of errno.
extern errno;
void*
f(void *arg)
{
printf("%u,%p\n", getpid(), &errno);
fflush(stdin);
return NULL;
}
int
main(int argc, char **argv)
{
pthread_t tid;
pthread_create(&tid, NULL, f, NULL);
printf("%u,%p\n", getpid(), &errno);
fflush(stdin);
pthread_join(tid, NULL);
return 0;
}
Then, why?

I'm not sure exactly how clone() is used when pthread_create() is called. That said, looking at the clone() man page, it looks like there is a flag called CLONE_THREAD which:
If CLONE_THREAD is set, the child is
placed in the same thread group as the
calling process. To make the remainder
of the discussion of CLONE_THREAD more
readable, the term "thread" is used to
refer to the processes within a thread
group.
Thread groups were a feature added in
Linux 2.4 to support the POSIX threads
notion of a set of threads that share
a single PID. Internally, this shared
PID is the so-called thread group
identifier (TGID) for the thread
group. Since Linux 2.4, calls to
getpid(2) return the TGID of the
caller.
It then goes on to talk about a gettid() function for getting the unique ID of an individual thread within a process. Modifying your code:
#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <unistd.h>
int errno;
void*
f(void *arg)
{
printf("%u,%p, %u\n", getpid(), &errno, syscall(SYS_gettid));
fflush(stdin);
return NULL;
}
int
main(int argc, char **argv)
{
pthread_t tid;
pthread_create(&tid, NULL, f, NULL);
printf("%u,%p, %u\n", getpid(), &errno, syscall(SYS_gettid));
fflush(stdin);
pthread_join(tid, NULL);
return 0;
}
(make sure to use "-lpthread"!) we can see that the individual thread id is indeed unique, while the pid remains the same.
rascher#coltrane:~$ ./a.out
4109,0x804a034, 4109
4109,0x804a034, 4110

Global variables: your mistake is that errno is not a global variable but a macro that expands to an lvalue of type int. In practice, it expands to (*__errno_location()) or similar.
getpid is a library function that returns the process id in the POSIX sense of process, not the bogus Linux per-clone pid. Nowadays Linux has the minimal kernel-level functionality necessary to make near-POSIX-compliance possible with respect to threads, but most of it still depends on ugly hacks at the userspace libc level.

Related

How to solve race condition?

Value of Global variable var in main() function sometimes comes -1 and sometimes 1 .How to write a robust code without using sleep function so that thread get time to get started and running .
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int var = -1; // GLobal Variable
void *myThreadFun(void *vargp)
{
var = 1;
return NULL;
}
int main()
{
pthread_t thread_id;
printf("Before Thread\n");
pthread_create(&thread_id, NULL, myThreadFun, NULL);
printf("var=%d",var);
pthread_join(thread_id, NULL);
printf("After Thread\n");
exit(0);
}
Value of Global variable var in main() function sometimes comes -1 and
sometimes 1 .How to write a robust code without using sleep function
so that thread get time to get started and running .
It is a distressingly common misconception among those new to multithreaded programming that problems such as yours are a matter of timing. That is not the case, at least not from the perspective of the threading and memory models of most modern high-level programming languages. No amount of delay alone ensures that one thread will see the effects on memory produced by another, therefore robust code does not use timing functions such as sleep() for that purpose.
Rather, the issue is one of synchronization. This is the area that contains rules about what writes to memory by one thread must be visible to other threads. It also covers special kinds of objects and functions that serve to enable threads to affect the execution of other threads, generally by temporarily blocking them from proceeding. These two facets are closely linked.
The pthread_create() and pthread_join() functions have synchronization effects. Among other things, all writes to memory by a thread T1 before it calls pthread_create() to start a thread T2 are visible to T2 (modulo subsequent rewrites of the same memory). All writes to memory by T2 are visible to T1 after it successfully joins T2 via pthread_join(). Therefore, one solution to the question as posed is to wait until after joining the second thread before attempting to read var, as #Robert's answer suggests.
If that is undesirable, then you'll need to engage some other kind of synchronization mechanism to make the main thread wait for the second to update var. Such a wait on a synchronization object will also have the effect of making the second thread's write visible to the main thread.
The most general-purpose synchronization technique offered by pthreads is the condition variable which must be used in conjunction with a mutex. You will find many explanations here on SO and elsewhere about how properly to use a CV.
For your particular case, however, you might find a semaphore easier to set up and use. Semaphores are technically separate from the pthreads library proper, but they have suitable synchronization semantics, both for making threads wait and for making memory operations of one thread visible to another. That might look like this:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
int var = -1; // GLobal Variable
sem_t semaphore;
void *myThreadFun(void *vargp)
{
var = 1;
// increment the semaphore's value
sem_post(&semaphore);
return NULL;
}
int main()
{
pthread_t thread_id;
// initialize the semaphore with value 0
sem_init(&semaphore, 0, 0);
printf("Before Thread\n");
pthread_create(&thread_id, NULL, myThreadFun, NULL);
// Wait until the semaphore's value can be decremented by one without
// it becoming negative (and then perform the decrement before proceeding).
sem_wait(&semaphore);
printf("var=%d",var);
pthread_join(thread_id, NULL);
printf("After Thread\n");
exit(0);
}
I think your code is robust, it's just where you print the result which is incorrect. You need to ensure your thread has finished his work before printing the result.
If you print the result before calling pthread_join, there are two possibilities:
myThreadFun has already changed var, in such case var will contain the value 1
myThreadFun hasn't been completely executed, in such case, var will have its initial value -1.
If you print the result after calling pthread_join, the function myThreadFun will be fully executed and it will print 1.
int main()
{
pthread_t thread_id;
printf("Before Thread\n");
pthread_create(&thread_id, NULL, myThreadFun, NULL);
pthread_join(thread_id, NULL);
printf("After Thread\n");
printf("var=%d",var); /* Here, the thread has completed */
exit(0);
}
Robert's solution is sensible, but I believe you don't actually want to wait for the thread to complete.
If you want the main thread to wait for the variable to be set by the thread without waiting for the thread to end, you will need some kind of synchronization. I'll use a semaphore, but there are a number of other solutions.
#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>
#include <stdlib.h>
#include <unistd.h>
static sem_t started_threads_sem;
static int var;
static void *myThreadFun(void *vargp) {
sleep(3); // This is the thread doing some initialization.
var = 1;
sem_post(&started_threads_sem);
sleep(3); // This is the thread doing stuff.
return NULL;
}
int main() {
printf("Before Thread\n");
sem_init(&started_threads_sem, 0, 0);
pthread_t thread_id;
pthread_create(&thread_id, NULL, myThreadFun, NULL);
// Wait for the thread to have started.
sem_wait(&started_threads_sem);
printf("var=%d\n", var);
pthread_join(thread_id, NULL);
printf("After Thread\n");
exit(0);
}
Before Thread
<3 s pause>
var=1
<3 s pause>
After Thread

How to get thread id of a pthread in linux c program?

In a Linux C program, how do I print the thread id of a thread created by the pthread library? For example like how we can get pid of a process by getpid().
What? The person asked for Linux specific, and the equivalent of getpid(). Not BSD or Apple. The answer is gettid() and returns an integral type. You will have to call it using syscall(), like this:
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
....
pid_t x = syscall(__NR_gettid);
While this may not be portable to non-linux systems, the threadid is directly comparable and very fast to acquire. It can be printed (such as for LOGs) like a normal integer.
pthread_self() function will give the thread id of current thread.
pthread_t pthread_self(void);
The pthread_self() function returns the Pthread handle of the calling thread. The pthread_self() function does NOT return the integral thread of the calling thread. You must use pthread_getthreadid_np() to return an integral identifier for the thread.
NOTE:
pthread_id_np_t tid;
tid = pthread_getthreadid_np();
is significantly faster than these calls, but provides the same behavior.
pthread_id_np_t tid;
pthread_t self;
self = pthread_self();
pthread_getunique_np(&self, &tid);
As noted in other answers, pthreads does not define a platform-independent way to retrieve an integral thread ID.
On Linux systems, you can get thread ID thus:
#include <sys/types.h>
pid_t tid = gettid();
On many BSD-based platforms, this answer https://stackoverflow.com/a/21206357/316487 gives a non-portable way.
However, if the reason you think you need a thread ID is to know whether you're running on the same or different thread to another thread you control, you might find some utility in this approach
static pthread_t threadA;
// On thread A...
threadA = pthread_self();
// On thread B...
pthread_t threadB = pthread_self();
if (pthread_equal(threadA, threadB)) printf("Thread B is same as thread A.\n");
else printf("Thread B is NOT same as thread A.\n");
If you just need to know if you're on the main thread, there are additional ways, documented in answers to this question how can I tell if pthread_self is the main (first) thread in the process?.
pid_t tid = syscall(SYS_gettid);
Linux provides such system call to allow you get id of a thread.
You can use pthread_self()
The parent gets to know the thread id after the pthread_create() is executed sucessfully, but while executing the thread if we want to access the thread id we have to use the function pthread_self().
This single line gives you pid , each threadid and spid.
printf("before calling pthread_create getpid: %d getpthread_self: %lu tid:%lu\n",getpid(), pthread_self(), syscall(SYS_gettid));
I think not only is the question not clear but most people also are not cognizant of the difference. Examine the following saying,
POSIX thread IDs are not the same as the thread IDs returned by the
Linux specific gettid() system call. POSIX thread IDs are assigned
and maintained by the threading implementation. The thread ID returned
by gettid() is a number (similar to a process ID) that is assigned by
the kernel. Although each POSIX thread has a unique kernel thread ID
in the Linux NPTL threading implementation, an application generally
doesn’t need to know about the kernel IDs (and won’t be portable if it
depends on knowing them).
Excerpted from: The Linux Programming Interface: A Linux and UNIX System Programming Handbook, Michael Kerrisk
IMHO, there is only one portable way that pass a structure in which define a variable holding numbers in an ascending manner e.g. 1,2,3... to per thread. By doing this, threads' id can be kept track. Nonetheless, int pthread_equal(tid1, tid2) function should be used.
if (pthread_equal(tid1, tid2)) printf("Thread 2 is same as thread 1.\n");
else printf("Thread 2 is NOT same as thread 1.\n");
pthread_getthreadid_np wasn't on my Mac os x. pthread_t is an opaque type. Don't beat your head over it. Just assign it to void* and call it good. If you need to printf use %p.
There is also another way of getting thread id. While creating threads with
int pthread_create(pthread_t * thread, const pthread_attr_t * attr, void * (*start_routine)(void *), void *arg);
function call; the first parameter pthread_t * thread is actually a thread id (that is an unsigned long int defined in bits/pthreadtypes.h). Also, the last argument void *arg is the argument that is passed to void * (*start_routine) function to be threaded.
You can create a structure to pass multiple arguments and send a pointer to a structure.
typedef struct thread_info {
pthread_t thread;
//...
} thread_info;
//...
tinfo = malloc(sizeof(thread_info) * NUMBER_OF_THREADS);
//...
pthread_create (&tinfo[i].thread, NULL, handler, (void*)&tinfo[i]);
//...
void *handler(void *targs) {
thread_info *tinfo = targs;
// here you get the thread id with tinfo->thread
}
For different OS there is different answer. I find a helper here.
You can try this:
#include <unistd.h>
#include <sys/syscall.h>
int get_thread_id() {
#if defined(__linux__)
return syscall(SYS_gettid);
#elif defined(__FreeBSD__)
long tid;
thr_self(&tid);
return (int)tid;
#elif defined(__NetBSD__)
return _lwp_self();
#elif defined(__OpenBSD__)
return getthrid();
#else
return getpid();
#endif
}
Platform-independent way (starting from c++11) is:
#include <thread>
std::this_thread::get_id();
You can also write in this manner and it does the same. For eg:
for(int i=0;i < total; i++)
{
pthread_join(pth[i],NULL);
cout << "SUM of thread id " << pth[i] << " is " << args[i].sum << endl;
}
This program sets up an array of pthread_t and calculate sum on each. So it is printing the sum of each thread with thread id.

Is APUE wrong about linux threads description?

In Figure 11.2 APUE 2nd, there is a code demoing usage for threads API, as below:
#include <pthread.h>
#include <stdio.h>
pthread_t ntid;
void printids(const char *s)
{
pid_t pid;
pthread_t tid;
pid = getpid();
tid = pthread_self();
printf("%s pid %u tid %u (0x%x)\n", s,
(unsigned int)pid, (unsigned int)tid, (unsigned int)(tid));
}
void *thr_fn(void *arg)
{
printids("new thread: ");
return (void*)0;
}
int main(void)
{
int err;
err = pthread_create(&ntid, NULL, thr_fn, NULL);
if (err != 0)
return -1;
printids("main thread: ");
sleep(1);
return 0;
}
and the book says the output is like this,
$./a.out
new thread: pid 6628 ...
main thread: pid 6626 ...
Pid is different ! This is because "Linux use the clone() to implement threads, same as fork(), so the system consider the threads as separate processes who share resources".
But When I tested, I found the result is different from the APUE result, which is
$ ./a.out
main thread: pid 13301 tid 3078153920 (0xb778e6c0)
new thread: pid 13301 tid 3078151024 (0xb778db70)
the pid is the same ! so is APUE outdated ? But linux do use clone to implement threads, and in linux kernel, they are viewed as different processes. How come the process ID is the same ?
There's a high chance that your edition APUE might be outdated in the sense that it refers to LinuxThreads instead of NPTL.
Here's the relevant section from the clone(2) manpage that sheds light on this issue:
"Thread groups were a feature added in Linux 2.4 to support the POSIX threads notion of a set of threads that share a single PID. Internally, this shared PID is the so-called thread group identifier (TGID) for the thread group. Since Linux 2.4, calls to getpid(2) return the TGID of the caller.
The threads within a group can be distinguished by their (system-wide) unique thread IDs (TID). A new thread's TID is available as the function result returned to the caller of clone(), and a thread can obtain its own TID using gettid(2)."

pthread_create from a child process

I'm sure I'm missing something basic, but I'm writing a program that fork()s several child processes, each of which create several pthreads. It seems that the pthread_create call never works from a child process. Here is sample code to explain what I mean:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
// Listen for a request from user proc i
void *wait_for_req(void *cvoid) {
int req;
int read_ret;
printf("new thread started\n");
pthread_exit(NULL);
}
void spawn_read_threads(int proc_num, int n) {
int i;
printf("About to spawn %d read threads\n", n);
for (i=0; i<n; i++) {
pthread_t *t;
printf("spawning new thread\n");
int create_result = pthread_create(t, NULL, wait_for_req, NULL);
printf("_create returned %d\n", create_result);
pthread_join(*t, NULL);
}
}
int main() {
if (!fork())
spawn_read_threads(0, 1);
}
The output of this program is
About to spawn 1 read threads
spawning new thread
But if I comment out if comment out if (!fork()):
About to spawn 1 read threads
spawning new thread
_create returned 0
new thread started
So why doesn't execution get through create_result in the first case?
And if this is useful:
rob#ubuntu:/mnt/hgfs/Virtual Machines$ uname -a
Linux ubuntu 2.6.32-24-generic #42-Ubuntu SMP Fri Aug 20 14:24:04 UTC 2010 i686 GNU/Linux
I can see one immediate problem with your code: pthread_create takes the address of an existing pthread_t variable and stores the new thread ID in it. You're passing an uninitialized pointer instead. You need to do something like:
pthread_t tid;
int create_result = pthread_create(&tid, NULL, wait_for_req, NULL);
I'd say you were just lucky when it worked once, because your current code essentially causes undefined behaviour.
Besides the errors you found in your answer, you are not supposed to call pthread_* from within the forked process. After, fork() only async-signal safe functions should be used. You must exec() first, and then you may create some pthreads.
pthread_t t;
printf("spawning new thread\n");
int create_result = pthread_create(&t, NULL, wait_for_req, NULL);
printf("_create returned %d\n", create_result);
pthread_join(t, NULL);

How do you query a pthread to see if it is still running?

In my destructor I want to destroy a thread cleanly.
My goal is to wait for a thread to finish executing and THEN destroy the thread.
The only thing I found about querying the state of a pthread is pthread_attr_setdetachstate but this only tells you if your thread is:
PTHREAD_CREATE_DETACHED
PTHREAD_CREATE_JOINABLE
Both of those have nothing to do with whether the thread is still running or not.
How do you query a pthread to see if it is still running?
It sounds like you have two questions here:
How can I wait until my thread completes?
Answer: This is directly supported by pthreads -- make your thread-to-be-stopped JOINABLE (when it is first started), and use pthread_join() to block your current thread until the thread-to-be-stopped is no longer running.
How can I tell if my thread is still running?
Answer: You can add a "thread_complete" flag to do the trick:
Scenario: Thread A wants to know if Thread B is still alive.
When Thread B is created, it is given a pointer to the "thread_complete" flag address. The "thread_complete" flag should be initialized to NOT_COMPLETED before the thread is created. Thread B's entry point function should immediately call pthread_cleanup_push() to push a "cleanup handler" which sets the "thread_complete" flag to COMPLETED.
See details about cleanup handlers here: pthread cleanup handlers
You'll want to include a corresponding pthread_cleanup_pop(1) call to ensure that the cleanup handler gets called no matter what (i.e. if the thread exits normally OR due to cancellation, etc.).
Then, Thread A can simply check the "thread_complete" flag to see if Thread B has exited yet.
NOTE: Your "thread_complete" flag should be declared "volatile" and should be an atomic type -- the GNU compilers provide the sig_atomic_t for this purpose. This allows the two threads consistent access the same data without the need for synchronization constructs (mutexes/semaphores).
pthread_kill(tid, 0);
No signal is sent, but error checking is still performed so you can use that to check
existence of tid.
CAUTION: This answer is incorrect. The standard specifically prohibits passing the ID of a thread whose lifetime has ended. That ID might now specify a different thread or, worse, it might refer to memory that has been freed, causing a crash.
I think all you really need is to call pthread_join(). That call won't return until the thread has exited.
If you only want to poll to see whether the thread is still running or not (and note that is usually not what you should be wanting to do!), you could have the thread set a volatile boolean to false just before it exits... then your main-thread could read the boolean and if it's still true, you know the thread is still running. (if it's false, on the other hand, you know the thread is at least almost gone; it may still be running cleanup code that occurs after it sets the boolean to false, though, so even in this case you should still call pthread_join before trying to free any resources the thread might have access to)
There is not fully portable solution, look if your platform supports pthread_tryjoin_np or pthread_timedjoin_np. So you just check if thread can be joined (of course created with PTHREAD_CREATE_JOINABLE).
Let me note on the "winning" answer, which has a huge hidden flaw, and in some contexts it can lead to crashes. Unless you use pthread_join, it will coming up again and again. Assume you are having a process and a shared library. Call the library lib.so.
You dlopen it, you start a thread in it. Assume you don't want it join to it, so you set it detachable.
Process and shared lib's logic doing its work, etc...
You want to load out lib.so, because you don't need it any more.
You call a shutdown on the thread and you say, that you want to read a flag afterwards from your lib.so's thread, that it have finished.
You continue on another thread with dlclose, because you see, that you have saw, that the flag is now showing the thread as "finished"
dlclose will load out all stack and code related memory.
Whops, but dlclose does not stop threads. And you know, even when you are in the last line of the cleanup handler to set the "thread is finished" volatile atomic flag variable, you still have to return from a lot of methods on the stack, giving back values, etc. If a huge thread priority was given to #5+#6's thread, you will receive dlclose before you could REALLY stop on the thread. You will have some nice crashes sometimes.
Let me point out, that this is not a hipothetical problem, I had the same issue on our project.
I believe I've come up with a solution that at least works for Linux. Whenever I create a thread I have it save it's LWP (Light Weight Process ID) and assign it a unique name, eg.
int lwp = syscall(SYS_gettid);
prctl(PR_SET_NAME, (long)"unique name", 0, 0, 0);
Then, to check if the thread exists later I open /proc/pid/task/lwp/comm and read it. If the file exists and it's contents match the unique name I assigned, the thread exists. Note that this does NOT pass a possibly defunct/reused TID to any library function, so no crashes.
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <pthread.h>
#include <sys/prctl.h>
#include <sys/file.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <syscall.h>
pthread_t subthread_tid;
int subthread_lwp;
#define UNIQUE_NAME "unique name"
bool thread_exists (pthread_t thread_id)
{
char path[100];
char thread_name[16];
FILE *fp;
bool thread_exists = false;
// If the /proc/<pid>/task/<lwp>/comm file exists and it's contents match the "unique name" the
// thread exists, and it's the original thread (TID has NOT been reused).
sprintf(path, "/proc/%d/task/%d/comm", getpid(), subthread_lwp);
fp = fopen(path, "r");
if( fp != NULL ) {
fgets(thread_name, 16, fp);
fclose(fp);
// Need to trim off the newline
thread_name[strlen(thread_name)-1] = '\0';
if( strcmp(UNIQUE_NAME, thread_name) == 0 ) {
thread_exists = true;
}
}
if( thread_exists ) {
printf("thread exists\n");
} else {
printf("thread does NOT exist\n");
}
return thread_exists;
}
void *subthread (void *unused)
{
subthread_lwp = syscall(SYS_gettid);
prctl(PR_SET_NAME, (long)UNIQUE_NAME, 0, 0, 0);
sleep(10000);
return NULL;
}
int main (int argc, char *argv[], char *envp[])
{
int error_number;
pthread_create(&subthread_tid, NULL, subthread, NULL);
printf("pthread_create()\n");
sleep(1);
thread_exists(subthread_tid);
pthread_cancel(subthread_tid);
printf("pthread_cancel()\n");
sleep(1);
thread_exists(subthread_tid);
error_number = pthread_join(subthread_tid, NULL);
if( error_number == 0 ) {
printf("pthread_join() successful\n");
} else {
printf("pthread_join() failed, %d\n", error_number);
}
thread_exists(subthread_tid);
exit(0);
}
#include <string.h>
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <unistd.h>
void* thread1 (void* arg);
void* thread2 (void* arg);
int main()
{
pthread_t thr_id;
pthread_create(&thr_id, NULL, thread1, NULL);
sleep(10);
}
void* thread1 (void* arg)
{
pthread_t thr_id = 0;
pthread_create(&thr_id, NULL, thread2, NULL);
sleep(5);
int ret = 0;
if( (ret = pthread_kill(thr_id, 0)) == 0)
{
printf("still running\n");
pthread_join(thr_id, NULL);
}
else
{
printf("RIP Thread = %d\n",ret);
}
}
void* thread2 (void* arg)
{
// sleep(5);
printf("I am done\n");
}

Resources