Pthread Run a thread right after it's creation - c

I have a C program in which I use pthread.
I would like newly created threads to run as soon as they are created.
The reason behind this is that my threads have initialisation code to set up signal handlers, and I must be sure the handlers are ready, before my main thread sends some signals.
I've tried doing pthread_yield just after my pthread_create, but without success.
I doubt it makes a difference, but I am running Linux 3.6 on x86_64.
Thanks

If your goal is to have the main thread wait for all threads to reach the same point before continuing onward, I would suggest using pthread_barrier_wait:
void worker(void*);
int main(int argc, char **argv)
{
pthread_barrier_t b;
pthread_t children[TCOUNT];
int child;
/* +1 for our main thread */
pthread_barrier_init(&b, NULL, TCOUNT+1);
for (child = 0; child < TCOUNT; ++child)
{
pthread_create(&children[child], NULL, worker, &b);
}
printf("main: children created\n");
/* everybody who calls barrier_wait will wait
* until TCOUNT+1 have called it
*/
pthread_barrier_wait(&b);
printf("main: children finished\n");
/* wait for children to finish */
for (child = 0; child < TCOUNT; ++child)
{
pthread_join(&children[child], NULL);
}
/* clean-up */
pthread_barrier_destroy(&b);
return 0;
}
void worker(void *_b)
{
pthread_barrier_t *b = (pthread_barrier_t*)_b;
printf("child: before\n");
pthread_barrier_wait(b);
printf("child: after\n");
}

Or you might use a barrier, i.e. call pthread_barrier_wait (early in the routine of each thread, or at initialization in the main thread), to ensure that every relevant thread has reached the barrier (after which some of your threads could do your naughty signal tricks). See this question.

Related

Pthread create is not starting the thread

I’m using pthread to start a thread, but the create function itself is not starting the thread
But instead if i call pthread join, it starts so actually should i call p thread join?
i heard from some answers that pthread join is not required , my pthread create function is called from main
int main(void) {
printf("-----------Welcome------\n");
Start_Generation();
return 0;
}
int Start_Generation(void)
{
ret=pthread_create(&C_AO_GENERATION_THREAD, NULL, C_Aogeneration_thread,(void*) message1);
if(ret!=0)
{
printf("Error Starting Thread\n");
return -1;
}
else
{
printf("AO Thread Started\n");
}
//ret=pthread_join(C_AO_GENERATION_THREAD, NULL);
return 0;
}
void *C_Aogeneration_thread (void *ptr)
{
char *message;
message = (char *) ptr;
unsigned int prof_gen_count;
unsigned int written_sample=0;
unsigned int curr_idx=0;
int ch=0;
int written=0;
printf("%s",message);
printf(" Generation Started\n");
prof_gen_count=(samplingrate/10);
while(stopflag)
{
printf("Thread is working\n");
}
return 0;
}
enter code here
I’m using pthread to start a thread, but the create function itself is not starting the thread
As presented in the question, your main thread terminates by returning from main immediately after reporting on the success or failure of the pthread_create() call, so
the whole program terminates at that point, apparently before the child progresses far enough to present any evidence that it is running, but also
there is no point in using a separate thread.
But instead if i call pthread join, it starts so actually should i call p thread join?
A call to pthread_join() does not return successfully until the specified thread has terminated. That is, in fact, its purpose. As a rule of thumb, you should either join or detach every thread you create. Joining is usually what you want, and note, too, that detaching a thread does not prevent the process from terminating and taking that thread with it when the main thread returns or exit()s.

Wait termination of threads work before close a server after receiving SIGINT or SIGTERM (Posix thread in C)

I'm developing a client / server in C using pthread.
It's a card game where server is the dealer between two clients that play.
I have this situation
server.c:
main:
int main (int argc, char * argv[])
using as a thread dispatcher for listening eventually entering connection on accept
pthread_create(&sig_thread, NULL, &thread_signal_handler, &server_Socket );
thread to catch signals (maskered conveniently) created inside main function
pthread_create(&tid[i++], NULL, &worker, (void*) arr_args)
every client is associated to a thread created (tid is the array of thread ID)
pthread_join(sig_thread, NULL)
to join thread for signals
pthread_join(tid[i], NULL)
to join thread created for every client connected.
worker:
void * worker(void * args)
do his job and terminated
thread signal handler:
void * thread_signal_handler(void * arg)
void * thread_signal_handler(void * arg) {
sigset_t set;
int sig, n;
int * socket = (int*) arg;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigaddset(&set,SIGTERM);
while (server_UP)
{
/* wait for a signal */
if (sigwait(&set, &sig))
perror("Sigwait");
/* received SIGINT or SIGTERM - closing server */
if ((sig == SIGINT || sig == SIGTERM)) {
printf(TERM_SERVER"\n");
server_UP = 0; /* global variable */
/* close socket blocked on MAIN */
shutdown( *socket, SHUT_RDWR );
}
return (void *) EXIT_SUCCESS;
}
In this way, the signal is catched well and the server is terminated immediately.
I need, if there are matches in progress, to waiting that all the workers finish their jobs properly, so I want to know how to say to thread handler "did you receive a SIGINT (or SIGTERM)? Ok, waiting the termination of all workers".
Any suggests? If you need more code, i'll edit this post.
When you create them you can save all of the threads in an array or a list and at the end call pthread_join() on all of them.
while (pthread_list) {
pthread_join(pthread_list->th_id, NULL);
pthread_list = pthread_list->next;
}
If you don't want to keep track of all threads you can keep a count of running threads, increment it before calling pthread_create, decrement the count as each thread finishes.
Then in the handler you'll sleep for some seconds iteratively until the count becomes 0.

how to wait for starting thread to have executed init code

I'm having trouble synchronizing a master thread to a recently started child thread.
What I want to do is:
master thread creates a new child thread and blocks
child thread starts and initializes (might take some time)
once the child thread is initialized, the main thread continues (and the two threads run in parallel)
My first attempt was something like:
typedef struct threaddata_ {
int running;
} threaddata_t;
void*child_thread(void*arg) {
threaddata_t*x=(threaddata_t)arg;
/* ... INITIALIZE ... */
x->running=1; /* signal that we are running */
/* CHILD THREAD BODY */
return 0;
}
void start_thread(void) {
threaddata_t*x=(threaddata_t*)malloc(sizeof(threaddata_t));
x->running=0;
int result=pthread_create(&threadid, 0, child_thread, &running);
while(!x->running) usleep(100); /* wait till child is initialized */
/* MAIN THREAD BODY */
}
Now I didn't like this at all, because it forces the main thread to sleep for probably a longer period than necessary.
So I did a 2nd attempt, using mutexes&conditions
typedef struct threaddata_ {
pthread_mutex_t x_mutex;
pthread_cond_t x_cond;
} threaddata_t;
void*child_thread(void*arg) {
threaddata_t*x=(threaddata_t)arg;
/* ... INITIALIZE ... */
pthread_cond_signal(&x->x_cond); /* signal that we are running */
/* CHILD THREAD BODY */
return 0;
}
void start_thread(void) {
threaddata_t*x=(threaddata_t*)malloc(sizeof(threaddata_t));
pthread_mutex_init(&x->x_mutex, 0);
pthread_cond_init (&x->x_cond , 0);
pthread_mutex_lock(&x->x_mutex);
int result=pthread_create(&threadid, 0, child_thread, &running);
if(!result)pthread_cond_wait(&x->x_cond, &x->x_mutex);
pthread_mutex_unlock(&x->x_mutex);
/* MAIN THREAD BODY */
}
This seemed more sane than the first attempt (using proper signals rather than rolling my own wait loop), until I discovered, that this includes a race condition:
If the child thread has finished the initialization fast enough (before the main thread waits for the condition), it will deadlock the main thread.
I guess that my case is not so uncommon, so there must be a really easy solution, but I cannot see it right now.
Proper way of condvar/mutex pair usage:
bool initialised = false;
mutex mt;
convar cv;
void *thread_proc(void *)
{
...
mt.lock();
initialised = true;
cv.signal();
mt.unlock();
}
int main()
{
...
mt.lock();
while(!initialised) cv.wait(mt);
mt.unlock();
}
This algorithm avoids any possible races. You can use any complex condition modified when mutex locked (instead of the simple !initialised).
The correct tool for that are sem_t. The main thread would initialize them with 0 and wait until it receives a token from the newly launched thread.
BTW your mutex/cond solution has a race condition because the child thread is not locking the mutex.
A barrier should do the trick nicely. Since you mention the need for support on Win32 in comments, barriers are supported on the latest Win32 pthreads, so you shouldn't have to write your own wrapper to get some portability between Win32 and *nix.
Something like:
typedef struct threaddata_ {
pthread_barrier_t* pbarrier;
} threaddata_t;
void* child_thread(void*arg) {
threaddata_t*x=(threaddata_t*)arg;
/* ... INITIALIZE ... */
int result = pthread_barrier_wait(x->pbarrier);
/* CHILD THREAD BODY */
return 0;
}
void start_thread(void) {
pthread_barrier_t barrier;
int result = pthread_barrier_init(&barrier, NULL, 2);
threaddata_t*x=(threaddata_t*)malloc(sizeof(threaddata_t));
x->pbarrier = &barrier;
int result=pthread_create(&threadid, 0, child_thread, &x);
result = pthread_barrier_wait(&barrier);
/* child has reached the barrier */
pthread_barrier_destroy(&barrier); /* note: the child thread should not use */
/* the barrier pointer after it returns from*/
/* pthread_barrier_wait() */
/* MAIN THREAD BODY */
}
The drawback to this solution is that it may needlessly blocks the child thread momentarily. If that's a problem, the condition variable solution mentioned by Dmitry Poroh is the way to go.

Pthreads and signals

I'm having a little trouble with pthreads. Basically, I want to catch a SIGINT and have all threads cleanup and exit. What I have (skeleton code):
main.c:
sig_atomic_t running;
void handler(int signal_number)
{
running = 0;
}
int main(void)
{
queue job_queue = new_job_queue();
running = 1;
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = &handler;
sigaction(SIGINT, &sa, NULL);
/* create a bunch of threads */
init_threads(&job_queue);
while(running) {
/* do stuff */
}
cleanup();
return (0);
}
threads.c
extern sig_atomic_t running;
pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER;
sem_t queue_count;
void init_threads(queue *q)
{
int numthreads = 12; /* say */
sem_init (&queue_count, 0, 0);
pthread_t worker_threads[numthreads];
int i;
for(i=0;i<numthreads;i++)
pthread_create(&worker_threads[i], NULL, &thread_function, q);
}
void * thread_function(void *args)
{
pthread_detatch(pthread_self());
queue *q = (queue *)args;
while(running) {
job *j = NULL;
sem_wait(&queue_count);
pthread_mutex_lock(&queue_mutex);
j = first_job_in_queue(q);
pthread_mutex_unlock(&queue_mutex);
if(j) {
/*do something*/
}
}
return (NULL);
}
I am having little luck with this. Since you're not guarenteed which thread gets the signal I thought this was a good way to go. But I am having a problem where sem_wait() in threads.c is hanging, which is expected but not desired. The while(running) loop in threads.c seems redundant. Should I maybe do a pthread_kill() to all the threads from main? Any obvious problems with the above skeleton code? Is there a better/easier way to go about doing this?
Thanks.
What you can do is to call sem_post() from the handler until all threads are unlocked. In the thread function, immediately after sem_wait() you should check the value of the running variable and if it's zero break breom the while.
The code in the handler could be something like the following:
int sval;
sem_getvalue(&queue_count, &sval);
while (sval < 0) {
sem_post(&queue_count);
sem_getvalue(&queue_count, &sval);
}
Of course return values should be verified for errors
You can catch SIGINT in one thread, and use pthread_sigmask() to block SIGINT in all other threads, if SIGINT generated by some way, the signal will be delivered to the specified thread, that thread can call pthread_cancel() to cancel all other threads.
You may want to consider calling pthread_join after each call to pthread_create. This will allow for your main thread to wait until all threads are done executing.
But maybe I'm misunderstanding slightly... Do you want to wait for all threads to finish, or simply wait for one to finish, and then stop all others immediately?
You shouldn't do a pthread_kill() if you don't have to. I'm not to familiar with pthread_detatch() but if you are wanting your main() function to wait for the threads to finish, it would probably be better if your cleanup() function did a pthread_join() on each thread id returned from pthread_create() to wait for each thread to exit normally.
Also, as far as I can tell, sem_wait() is hanging because your semaphore value is initialized to 0. If you want say at most 5 threads to access the shared resource at a time, initialize the semaphore to 5, i.e. sem_init(&queue_count, 0, 5).

thread termination issue (c programming)

I'm working on an application for Linux in C which uses multiple threads. The threads which are spawned by the main function do most of the work, and therefore usually finish last. I'm seeing some strange behavior, and I believe it's due to the main thread terminating before the spawned threads have a chance to finish their jobs. Here's some sample code to illustrate what I'm talking about:
#define _POSIX_C_SOURCE 200112L
#define _ISOC99_SOURCE
#define __EXTENSIONS__
#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>
void
my_cleanup(void *arg)
{
printf("cleanup: %s\n", (char *)arg);
}
void *
thread_stuff(void *arg)
{
printf("thread started\n");
pthread_cleanup_push(cleanup, "running");
if (arg)
pthread_exit((void *)2);
pthread_cleanup_pop(0);
pthread_exit((void *)2);
}
int
main()
{
int err;
pthread_t tid1, tid2;
err = pthread_create(&tid1, NULL, thread_stuff, (void *)1);
err = pthread_create(&tid2, NULL, thread_stuff, (void *)1);
sleep(10); /* change the value here if you want */
return SUCCESS;
}
When this code is run, the message from the cleanup function is printed twice, as it should be, but other times when it is run, I see the message printed only once sometimes, and other times I see it printed three times or not at all. You add in the sleep function in the main function to play with how long it takes the main function to terminate.
What can I do to make the program run as it should? I suspect it has something to do with joining to the children, but I don't entirely understand the concept of a join or how to apply it to this situation.
Thanks in advance!
Yes, you should "join" the threads. "Joining" a thread simply means waiting until the thread has terminated. In other words, you would do
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
to wait until both threads have terminated.
Edit: What to do if you have a child thread which, in turn, creates a "grandchild" thread? As a rule, whoever created the thread should wait for it to terminate ("join" it). So in this scenario, the child thread would call phtread_join on the grandchild thread, and the main thread would call join on the child thread.
I think you want to run pthread_join on each of the threads when your main thread completes -- this makes the main thread stop until the given thread finishes running. Other threads can still complete first though, so running pthread_join on every thread will prevent the main thread from terminiating until all of the others have terminated.
There is a definite problem if main() finishes before the threads it spawned if you don't call pthread_exit() explicitly. All of the threads it created will terminate because main() is done and no longer exists to support the threads.
By having main() explicitly call pthread_exit() as the last thing it does, main() will block and be kept alive to support the threads it created until they are done.
int main()
{
int err;
pthread_t tid1, tid2;
err = pthread_create(&tid1, NULL, thread_stuff, (void *)1);
err = pthread_create(&tid2, NULL, thread_stuff, (void *)1);
sleep(10); /* change the value here if you want */
/* Add the pthread_exit */
pthread_exit(NULL);
return SUCCESS;
}
Refer for more info here

Resources