pthread_create from a child process - c

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

Related

How to get the id of a pthread which is given when it is created?

When creating an pthread, pthread_create() is used. First parameter of this function is thread_id.
I tried to access this value pthread_self() but this gives something very big and not the numbers I gave while creating.
Is there a way to access this value?
for(int i = 0; i < necessaryThreadCount; i++){
pthread_create(&threadIDs[i], NULL, theFunction, (void*)&requiredStructre[i]);
}
my question is, how can i access the value of given threadID inside theFunction?
Solution:
I just added another variable to the struct I pass as parameter.
First parameter is pointer to thread_id which you need to declare first.
ID will get assigned after you create thread using pthread_create(). refer the below:
int main()
{
pthread_t thread; // declare thread
pthread_create(&thread, NULL, func, NULL);
printf("the thread id = %d\n", thread);
}
thread_id is for the new thread that is created. if you execute pthread_self() in the current thread it returns a different value from the newly created thread.
Hope the below example may help you to understand thread id creation:
[NOTE: not a good idea to have global pthread_t declared]
Example:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
pthread_t ctid;
void* thread_function(void* arg)
{
printf("Inside the thread\n");
printf("ctid: %ld, self: %ld", ctid, pthread_self());
// exit the current thread
pthread_exit(NULL);
}
void createthread()
{
pthread_create(&ctid, NULL, &thread_function, NULL);
printf("This line may be printed"
" before thread terminates\n");
// Waiting for the created thread to terminate
pthread_join(ctid, NULL);
pthread_exit(NULL);
}
// Driver code
int main()
{
createthread();
return 0;
}

pthread_exit() is reached before pthread_join call

Having this piece of code:
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void* PrintHello(void* data){
printf("Hello from new thread\n");
pthread_exit(NULL);
}
int main(int argc, char* argv[]){
int rc;
pthread_t thread_id;
T_DATA data;
Data = init_data();
rc = pthread_create(&thread_id, NULL, PrintHello, (void*)data);
if(rc){
printf("\n ERROR: return code from pthread_create is %d \n", rc);
exit(1);
}
sleep(100);
printf("\n Created new thread (%d) ... \n", thread_id);
pthread_join(thread_id);
}
When main creates the new thread and then perform sleep(100), the new thread probably reach pthread_exit before main reach pthread_join. Anyways the new thread waits and his resources are not freed until main perform pthread_join so if i execute ps command i will see the new thread during next 100 seconds, am i right?. I would get the same behavior if I use pthread_detach instead pthread_join? I wonder what happen when the new thread perform the pthread_exit before main perform pthread_detach over the thread.
The thread cannot be cleaned up until it terminates, of course. But it also cannot be cleaned up until it is either joined or detached. A thread that terminates without being detached will keep enough information around to allow another thread to join it.

Return code from pthread_create() is 11

I am trying to run a simple multi threaded programming and i am getting this error from gcc
return code from pthread_create() is 11
how do i solve this issue ?
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 20000
void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0; t<NUM_THREADS; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Last thing that main() should do */
pthread_exit(NULL);
}
Well, you could start with determining what the error actually means. According to this and this (other resources will tell you the same information, this is just an example), the number 11 stands for EAGAIN which in turn means "The system lacked the necessary resources to create another thread, or the system-imposed limit on the total number of threads in a process PTHREAD_THREADS_MAX would be exceeded.".
That matches the fact that your are trying to create 20.000(!) threads. Create less threads, or wait until threads complete before starting new ones.
Note that the maximum number of threads that can be created depends on your system (and possibly even depends on a number of other settings). Google for "How to Find PTHREAD_THREADS_MAX" if you really need to know.
However, unless this is just a trivial example for toying around (or maybe even then) you might want to look into the concept of thread pools and queues.

Creating multiple threads and invoking other exectuables in Cygwin through system()?

I am working on a project in Cygwin. In an attempt to create multiple threads in C, and each thread calls another executable through the command line using the system() function, it turns out things are not working properly. Specifically, the code I have is like this:
#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS 5
void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
system("date ");
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0; t<NUM_THREADS; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
But it does not work. The error I get is segmenetation fault with stack overflows. Anyway has an idea on how to call other executables in the system shell in parallel by creating multiple threads?
Thanks.
Add this code :
for(t=0; t<NUM_THREADS; t++){
pthread_join(threads[t], NULL);
}
before
pthread_exit(NULL);
as called in main().
Several bugs here:
In the main() function, after you create the thread, you should use pthread_exit() to exit from all the individual thread. So exit() use is not right here.
In the end of the main() function, just before you terminate the main thread, call pthread_join() to wait for all the individual thread to terminate.
At the end after all the child threads have terminated, you can call exit() to terminate the process itself.
http://www.thegeekstuff.com/2012/04/terminate-c-thread/
That issue looks worth reporting to the Cygwin mailing list.
What you can do instead is to do away with threads and use fork()/exec() or spawn(_P_NOWAITO, ...) to create the child processes.
(spawn() actually is a family of functions; see /usr/include/process.h for details. Its use is recommended as it avoids Cygwin's high fork overhead.)

How does POSIX Threads work in linux?

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.

Resources