Pthread create as detached - c

I have a problem creating a thread as detached. Here's the code I wrote:
void* testFunction() {
pthread_attr_t attr;
int chk,rc;
pthread_attr_init(&attr);
printf("thread_attr_init: %d\n",rc);
pthread_attr_getdetachstate(&attr, &chk);
printf("thread_attr_getdetachedstate: %d\n",rc);
if(chk == PTHREAD_CREATE_DETACHED )
printf("Detached\n");
else if (chk == PTHREAD_CREATE_JOINABLE)
printf("Joinable\n");
return NULL;
}
int main (int argc, const char * argv[]) {
pthread_t thread1;
pthread_attr_t attr;
int rc;
rc = pthread_attr_init(&attr);
printf("attr_init: %d\n",rc);
rc = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
printf("attr_setdetachedstate: %d\n",rc);
rc = pthread_create(&thread1, &attr, testFunction, NULL);
printf("attr_create: %d\n",rc);
sleep(4);
pthread_cancel(thread1);
return 0;
}
The problem is that testFunction() always print "Joinable". Can anyone tell me where I'm getting wrong?

Try running the following code. That should clear the confusion.
/*------------------------------- join_01.c --------------------------------*
On Linux, compile with:
cc -std=c99 -pthread join_01.c -o join_01
gcc join_01.c -o join_01 -std=c99 -lpthread (Ubuntu)
Check your system documentation how to enable C99 and POSIX threads on
other Un*x systems.
Copyright Loic Domaigne.
Licensed under the Apache License, Version 2.0.
*--------------------------------------------------------------------------*/
#include <unistd.h> // sleep()
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h> // EXIT_SUCCESS
#include <string.h> // strerror()
#include <errno.h>
/***************************************************************************/
/* our macro for errors checking */
/***************************************************************************/
#define COND_CHECK(func, cond, retv, errv) \
if ( (cond) ) \
{ \
fprintf(stderr, "\n[CHECK FAILED at %s:%d]\n| %s(...)=%d (%s)\n\n",\
__FILE__,__LINE__,func,retv,strerror(errv)); \
exit(EXIT_FAILURE); \
}
#define ErrnoCheck(func,cond,retv) COND_CHECK(func, cond, retv, errno)
#define PthreadCheck(func,rc) COND_CHECK(func,(rc!=0), rc, rc)
/*****************************************************************************/
/* thread- dummy thread */
/*****************************************************************************/
void*
thread(void* ignore)
{
sleep(1);
return NULL;
}
/*****************************************************************************/
/* detach_state. Print detachstate of a thread. */
/*****************************************************************************/
/*
* We find out indirectly if a thread is detached using pthread_join().
* If a thread is detached, then pthread_join() fails with EINVAL.
* Otherwise the thread is joined, and hence was joinable.
*
*/
void
detach_state(
pthread_t tid, // thread to check detach status
const char *tname // thread name
)
{
int rc; // return code
rc = pthread_join(tid, NULL);
if ( rc==EINVAL )
{
printf("%s is detached\n", tname);
}
else if ( rc==0 )
{
printf("%s was joinable\n", tname);
}
else
{
printf("%s: pthread_join() = %d (%s)\n",
tname, rc, strerror(rc)
);
}
}
/*****************************************************************************/
/* main- main thread */
/*****************************************************************************/
int
main()
{
pthread_t tid1, tid2, tid3; // thread 1,2 and 3.
pthread_attr_t attr; // thread's attribute
int rc; // return code
/*--------------------------------------------------------*/
/* 1st test: normal thread creation */
/*--------------------------------------------------------*/
rc = pthread_create(&tid1, NULL, thread, NULL);
PthreadCheck("pthread_create", rc);
detach_state(tid1, "thread1"); // expect: joinable
/*--------------------------------------------------------*/
/* 2nd test: detach thread from main thread */
/*--------------------------------------------------------*/
rc = pthread_create(&tid2, NULL, thread, NULL);
PthreadCheck("pthread_create", rc);
rc = pthread_detach(tid2);
PthreadCheck("pthread_detach", rc);
detach_state(tid2, "thread2"); // expect: detached
/*--------------------------------------------------------*/
/* 3rd test: create detached thread */
/*--------------------------------------------------------*/
// set detachstate attribute to DETACHED
//
rc=pthread_attr_init(&attr);
PthreadCheck("pthread_attr_init", rc);
rc=pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
PthreadCheck("pthread_attr_setdetachstate", rc);
// create thread now
//
rc = pthread_create(&tid3, &attr, thread, NULL);
PthreadCheck("pthread_create", rc);
detach_state(tid3, "thread3");
/*--------------------------------------------------------*/
/* that's all folks! */
/*--------------------------------------------------------*/
return EXIT_SUCCESS;
}
The output should be
$ ./join_01
thread1 was joinable
thread2 is detached
thread3 is detached

Your testFunction is not examining anything about the current thread, rather just the initially-detached flag of a completely new attribute object you just created. Moreover, it is completely impossible, in the POSIX threads API, to recover the attributes a thread was created with or determine if a thread is detached or not. You simply have to trust that the implementation behaves as required, just like you have to trust that, if malloc(100) returns a non-null pointer, it points to a location at which you can store at least 100 bytes. This is the nature of C.

Your testFunction is not reading the current thread's attributes. Instead of calling pthread_attr_init(), pthread_getattr_np() might help you if it's present on your system, but you will need to pass the pthread_t for the thread in question onto wherever it's being queried from.

Related

How to make a child thread waiting for the main thread

I've got 2 threads : one child which detects mouse events, and the other main one which execute the program.
global variable :
int g_wait = 0;
child thread :
void *mouseEvent2(void *arg)
{
int fd;
struct input_event ev;
const char* pFile = "/dev/input/event0";
signal(SIGINT, SAMPLE_VGS_HandleSig);
signal(SIGTERM, SAMPLE_VGS_HandleSig);
fd = open(pFile, O_RDONLY);
if (fd == -1) {
printf("ERROR Opening %s\n", pFile);
return NULL;
}
while(scroll != -1) {
read(fd, &ev, sizeof(ev));
[... Some code with if statement ... ]
if(...) //left mouse button
g_wait = !g_wait;
[need waiting so the thread won't use at 100% a core]
}
close(fd);
(void) arg;
pthread_exit(NULL);
}
Main thread :
int main() {
[... some code and initilisation here ...]
if(pthread_create(&scrollThread, NULL, mouseEvent2, NULL))
goto _FAILURE_;
do {
[...]
while(g_wait);
}
[... some deinit ...]
_FAILURE_ :
pthread_join(scrollThread, NULL);
[... some other deinit ...]
return 0;
}
My problem is : when my main is waiting, my child thread is using at 100% 1 core processor, so which function can I use to pause the child thread with the main one?
I already consult How to make main thread wait for all child threads finish? but it didn't help me totally.
So, if you want to pause main thread until child thread signals about it ends, you can use mutexes to lock main thread:
#include "stdio.h"
#include "pthread.h"
/* I work on windows now, so i need windows sleep function to test example */
/* platform independed sleep function */
#ifdef _WIN32
# include "windows.h"
# define platform_sleep(ms) Sleep(ms)
#else
# include "unistd.h"
# define platform_sleep(s) sleep(s / 1000)
#endif
pthread_mutex_t mtx;
void *
child_func(void *arg)
{
/* simulate some hard work */
platform_sleep(3000); /* 3 secs */
/* after this "hard work" we allow main thread to continue */
pthread_mutex_unlock(&mtx);
}
int
main()
{
pthread_mutex_init(&mtx, NULL);
pthread_mutex_lock(&mtx);
pthread_t child;
pthread_create(&child, NULL, child_func, NULL);
/* mutex is already locked by main thread, so it waits */
/* until child thread unlock it */
pthread_mutex_lock(&mtx);
pthread_mutex_destroy(&mtx);
/* do work after child ends */
}

Pthread: lock PTHREAD_MUTEX_ERRORCHECK mutex from non-owner thread

classical question please;
I didn't find confirmation from code;
C language.
I'm running the below code on Windows.
/* This is an implementation of the threads API of POSIX 1003.1-2001.*/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
//equivalent to PTHREAD_MUTEX_ERRORCHECK
void* thread_function(void *args)
{
int rc;
rc = pthread_mutex_unlock( & mutex );
printf( "[thread_function] pthread_mutex_unlock rc: %d \n", rc);
return 0;
}
int main(int argc, char* argv[])
{
int rc;
pthread_t id;
pthread_mutex_lock( &mutex );
rc = pthread_create(&id, NULL, thread_function, NULL);
pthread_join(id, NULL);
printf( "[main] completed\n");
}
rc = pthread_mutex_unlock( & mutex ); - returns rc equal to 1 which is as expected.
but when I change the code to rc = pthread_mutex_lock( & mutex ); - the error does not occur.
But in many Pthread API doc it is mentioned that:
"If the mutex type is PTHREAD_MUTEX_ERRORCHECK, then error checking shall be provided. If a thread attempts to relock a mutex that it has already locked, an error shall be returned."
But it is not returned for me, and the question why?
The only guess I have - it depends on PThread realization which I'm using.
And it also may depend on OS; i.e. same code and the same version of Pthread lib will give different result on Linux.
Can anyone please clarify?
Thanks!
When a thread tries to lock a mutex locked by another thread, it blocks. This is of course the whole point: it would be useless if it were an error. The error checking is for programs where a thread might try to lock a mutex it has already locked. That usually results from a logic bug, although one could simulate a recursive mutex with it or perhaps use the locked state of the mutex as some sort of memory.
Generally, when you tried to lock mutex(Default Type) second time in the same thread your code has been blocked. To prevent this blocking situation, error checking mutex is used.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#define IN_MAIN ""
#define IN_THREAD "\t"
#define START_MAIN printf(IN_MAIN "\n-- Main Start -- \n");
#define END_MAIN printf(IN_MAIN "-- Main End -- \n\n"); \
exit(EXIT_SUCCESS);
#define ERROR_HANDLER(en, msg) \
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void * thread_routine(void * arg)
{
printf(IN_THREAD "-- Thread Start -- \n");
int ret;
pthread_mutex_lock(&mutex);
printf(IN_THREAD " Thread acquire lock for first time \n");
ret = pthread_mutex_lock(&mutex);
if(ret)
{
switch(ret)
{
case EDEADLK:
printf(IN_THREAD " A deadlock condition was detected \n");
break;
default:
ERROR_HANDLER(ret, "pthread_mutex_lock");
}
}
sleep(1);
ret = pthread_mutex_unlock(&mutex);
printf(IN_THREAD " Thread release lock first time -- %d \n", ret);
sleep(1);
ret = pthread_mutex_unlock(&mutex);
printf(IN_THREAD " Thread release lock second time -- %d \n", ret);
printf(IN_THREAD "-- Thread End --\n");
pthread_exit(NULL);
}
int main(int argc, char ** argv)
{
START_MAIN;
pthread_t thread_id;
pthread_mutexattr_t mutex_attr;
int mutex_type, ret=0;
pthread_mutexattr_init(&mutex_attr);
ret = pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ERRORCHECK);
if(ret)
ERROR_HANDLER(ret, "pthread_mutexattr_settype");
pthread_mutex_init(&mutex, &mutex_attr);
pthread_create(&thread_id, NULL, thread_routine, NULL);
pthread_join(thread_id, NULL);
END_MAIN;
}
Consider above example, when you execute the above code, it print "A deadlock condition was detected". This is because of the type of mutex is error check.
Now comment the line
ret = pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ERRORCHECK);
and execute the code. You'll notice your code is blocked after it print "Thread acquire lock for first time".
One of the mistakes in the Posix spec is the notion of "default" mutex type -- which is implementation dependent. Meaning the the semantics of a "default" mutex is any ones guess. Confusing? You bet.
My advice is to never use "default" for mutex type if you care about portability at all.

Simple example for pthread_join deadlock

I am looking for a very simple example to demonstrate a deadlock using pthread_join; however, this is not trivial.
I started with this:
void* joinit(void* tid)
{
pthread_t* tid_c = (pthread_t*)tid;
int retval = pthread_join(*tid_c, NULL);
printf("In joinit: tid = %d, retval = %d \n", *tid_c, retval);
return NULL;
}
int main()
{
pthread_t thread1;
pthread_t thread2;
pthread_create(&thread1, NULL, joinit, &thread2);
pthread_create(&thread2, NULL, joinit, &thread1);
pthread_join(thread2, NULL);
return 0;
}
But however, it says 'EINVAL' (invalid argument) because thread2 is not yet specified when pthread_create for thread1 is called.
Any ideas?
If you're just wanting to demonstrate that a pthread_join can cause a deadlock, you could do something similar to the following code:
#include <stdio.h>
#include <pthread.h>
void* joinit(void* tid)
{
printf("In %#x, waiting on %#x\n", pthread_self(), (*((pthread_t*)tid)));
pthread_join((*((pthread_t*)tid)), NULL);
printf("Leaving %#x\n", pthread_self());
return NULL;
}
int main(void)
{
pthread_t thread1 = pthread_self();
pthread_t thread2;
pthread_create(&thread2, NULL, joinit, &thread1);
joinit(&thread2);
return 0;
}
This will cause the main thread to wait on the spawned thread and the spawned thread to wait on the main thread (causing a guaranteed deadlock) without the need for extra locking primitives to clutter up what you are trying to demonstrate.
And to answer some of your questions more directly:
it says 'EINVAL' (invalid argument) because thread2 is not yet specified when pthread_create for thread1 is called.
... and from one of your comments ...
I tried this and it worked, but the problem is, it only works SOMETIMES because sometimes I get EINVAL again.
In your code, you call pthread_create consecutively to spawn the 2 threads:
pthread_create(&thread1, NULL, joinit, &thread2);
pthread_create(&thread2, NULL, joinit, &thread1);
In your joinit code, you grab the thread handle passed in to join on:
pthread_t* tid_c = (pthread_t*)tid;
int retval = pthread_join(*tid_c, NULL);
The reason this sometimes works and others you'll get EINVAL has to do with time slices allocated to each thread's context and sequencing. When the first pthread_create is called you will have a valid handle to thread1 after it returns but the handle to thread2 is not valid yet, at least not until the 2nd pthread_create is called.
To this, when a thread is created, the act of the thread coming "alive" (i.e. the thread function actually running) could take some extra time even though the thread handle returned is valid. In these instances, there is a chance one thread can execute more code than might be "expected". In your code, both pthread_create functions might happen to have been called in the time slice allocated for the main thread which could give each spawned thread enough "time" before hitting the pthread_join statement allowing tid_c to point to a valid handle; in the EINVAL case, pthread_create(&thread1, NULL, joinit, &thread2) was called and the spawned thread hit the pthread_join(*tid_c, NULL) before pthread_create(&thread2, NULL, joinit, &thread1) could give thread2 a valid handle (causing the error).
If you wanted to keep your code similar to how it is now, you would need to add a lock of some sort to ensure the threads don't exit or call anything prematurely:
#include <stdio.h>
#include <pthread.h>
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void* joinit(void* tid)
{
/* this can be above the lock because it will be valid after lock is acquired */
pthread_t* tid_c = (pthread_t*)tid;
int retval = -1;
pthread_mutex_lock(&lock);
pthread_mutex_unlock(&lock);
printf("%#x waiting on %#x\n", pthread_self(), *tid_c);
retval = pthread_join(*tid_c, NULL);
printf("In joinit: tid = %d, retval = %d \n", *tid_c, retval);
return NULL;
}
int main()
{
pthread_t thread1;
pthread_t thread2;
/* get the lock in the main thread FIRST */
pthread_mutex_lock(&lock);
pthread_create(&thread1, NULL, joinit, &thread2);
pthread_create(&thread2, NULL, joinit, &thread1);
/* by this point, both handles are "joinable", so unlock */
pthread_mutex_unlock(&lock);
/* can wait on either thread, but must wait on one so main thread doesn't exit */
pthread_join(thread2, NULL);
return 0;
}
Hope this can help.
The main reason for your error is that you have two threads each waiting for the same thread to terminate because of the call to pthread_join in main. Another problem is that you don't ensure each thread correctly sees the other thread's ID.
Fix it like this:
#include <stdio.h>
#include <pthread.h>
pthread_t thread1;
pthread_t thread2;
pthread_mutex_t mutex;
pthread_cond_t cond;
int go = 0;
void* joinit(void* ptr)
{
// wait until both thread IDs are known
pthread_mutex_lock(&mutex);
while (go == 0)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
pthread_t* tid_c = *((pthread_t**) ptr);
printf("About to wait\n");
int retval = pthread_join(*tid_c, NULL);
printf("In joinit: tid = %d, retval = %d \n", *tid_c, retval);
// tell the other threads we're done
pthread_mutex_lock(&mutex);
go++;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);
return NULL;
}
int main()
{
// setup synchronization
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
pthread_create(&thread1, NULL, joinit, &thread2);
pthread_create(&thread2, NULL, joinit, &thread1);
// tell the threads to go
pthread_mutex_lock(&mutex);
go = 1;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);
// wait for both threads to finish
pthread_mutex_lock(&mutex);
while (go != 3)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
return 0;
}

C - Threads using execl suicides itself

here's my problem: my code should execute all the executable files (i.e. all the binaries and all the scripts) in the current directory, concurrently.
Here's the code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <dirent.h>
/* struct created for passing arguments at every thread */
struct thread_data {
long thread_id;
char *nome_file;
};
/* task of every thread */
void *work(void *thread_args) {
long tid;
char *name;
struct thread_data *my_data;
my_data = (struct thread_data *)thread_args;
tid = my_data -> thread_id;
name = my_data -> nome_file;
printf("thread number %ld get file %s\n", tid, name);
execl(name, name, (char *)0);
printf("execl failed\n");
pthread_exit(NULL);
}
int filter(const struct dirent *entry) {
/* Filter for scandir(): I consider only the regular files */
if(entry -> d_type == DT_REG)
return 1;
else
return 0;
}
int main() {
int n, rc;
long t;
struct dirent **namelist;
pthread_attr_t attr;
void *status;
/* Number of regular files in the current directory */
n = scandir(".", &namelist, filter, alphasort);
if(n < 0) {
perror("scandir()");
exit(EXIT_FAILURE);
}
/* How many threads? */
pthread_t thread[n];
/* Every thread will receive one instance of the struct thread_data */
struct thread_data thread_data_array[n];
/* With this, I'm sure my threads will be joinable */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
for(t=0; t<n; t++) {
printf("Main: creating thread %ld\n", t);
/* Filling the arguments in the struct */
thread_data_array[t].thread_id = t;
thread_data_array[t].nome_file = namelist[t] -> d_name;
rc = pthread_create(&thread[t], &attr, work, (void *)&thread_data_array[t]);
if(rc) {
printf("ERROR: pthread_create() is %d\n", rc);
exit(EXIT_FAILURE);
}
}
pthread_attr_destroy(&attr);
for(t=0; t<n; t++) {
rc = pthread_join(thread[t], &status);
if(rc) {
printf("ERROR: pthread_join() is %d\n", rc);
exit(EXIT_FAILURE);
}
printf("Main: join succeeded on thread %ld\n", t);
}
printf("Main: program finished. Quitting...\n");
pthread_exit(NULL);
}
My program successfully reads the regular files in the current dir, and every thread get one file per time, but when the first binary or script is executed, the program quits!
Here's an example of its execution...
Main: creating thread 0
Main: creating thread 1
Main: creating thread 2
Main: creating thread 3
Main: creating thread 4
Main: creating thread 5
Main: creating thread 6
thread number 0 get file slide.pdf
execl failed
thread number 1 get file hello.sh
Congrats, you executed this script, I'm hello.sh!
And then, he won't continue the execution with other files. Perhaps the error is in the execl return value in case of success...
All of the exec-family functions replace the current process (not thread) by the named executable when they succeed; the only way they return is on failure. You should be using either fork followed by execl, or preferably, posix_spawn.

Problem while compiling pthreads program

I tried to compile this simple pthreads program with this command
$ gcc -pthread -o pthreads pthreads.c
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
void *myThread(void *arg);
int main()
{
pthread_t mythread;
int ret;
ret = pthread_create( &mythread, NULL, myThread, NULL );
if (ret != 0){
printf( "Can't create pthread: %s", strerror(errno));
exit(-1);
}
return 0;
}
void *myThread(void *arg){
// Thread code goes here..
printf("OK! NOW ON THE THREAD\n");
pthread_exit(NULL);
}
but when trying ./pthreads there is no output presented!!
You need to wait for the thread to finish. Otherwise you risk exiting before the thread starts executing.
...
pthread_create( &mythread, NULL, myThread, NULL );
...
// Wait for the thread to finish.
pthread_join( mythread, NULL);
You didn't wait for your thread to finish. You need to use pthread_join().
You problem comes from the fact that you're main thread is returning from main, and thus calling exit (or _exit). All running thread are killed when the program exit. In this case, the worker thread didn't have the time to execute before it is killed.
You can use pthread_join to wait for the completion of the thread before returning from main.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
void *myThread(void *arg);
int main()
{
void* thread_return;
pthread_t mythread;
int ret;
ret = pthread_create(&mythread, NULL, myThread, NULL);
if (ret != 0)
{
printf("Can't create pthread: %s\n", strerror(errno));
exit(-1);
}
ret = pthread_join(mythread, &thread_return);
if (ret != 0)
{
printf("Can't join pthread: %s\n", strerror(errno));
exit(-1);
}
return 0;
}
void *myThread(void *arg)
{
printf("OK! NOW ON THE THREAD\n");
pthread_exit(NULL);
}
Sanjit's answer is certainly correct, but for the sake of enlarging your threads toolbox, you might also look at pthread_barrier_wait. When you have a simple program with a lot of threads and main looks like "start all worker threads and wait for them to finish", having main and all the workers simply wait on a barrier can be a nice way to avoid having to store all the worker thread ids and join them in a for loop. Barriers also have a lot of other neat uses that sometimes let you avoid unnecessary complexity from doing the same things with mutexes and condition variables.

Resources