LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-08-2012, 04:48 AM   #1
wollowizard
LQ Newbie
 
Registered: May 2012
Posts: 13

Rep: Reputation: Disabled
Create two threads or nothing


Hi, I have the following problem.
Each time some event occurs, I want to create two threads to do some action. The problem is that I can check if the pthread_create fails, but I want that if the first pthread_create fails the second should not be done (easy) and also that if the second fails, the first thread, that has already been created, cleans the resources it's using and exits.

http://pastebin.com/tPmTyt4H

how can I do it?
 
Old 06-08-2012, 09:27 AM   #2
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 946Reputation: 946Reputation: 946Reputation: 946Reputation: 946Reputation: 946Reputation: 946Reputation: 946
Add synchronization to the worker threads, and use a flag to tell them to not do any work at all: like a starting gate, with a signal flag to tell the participants if the start failed.

All you really need is just a pthread_mutex_t and a flag variable. Have the thread creator first lock the mutex. If all threads can be created successfully, clear the flag, otherwise set it; then release the mutex. The worker threads first lock the same mutex, then check the value of the flag. If the flag is set, they unlock the mutex and abort. Otherwise they just unlock the mutex and start the real work.

It is simpler if you just add the functionality to the actual thread functions, but you can use a simple wrapper function and a related work spec if you need a more generic solution:
Code:
struct spec {
    pthread_mutex_t  *lock;
    int              *cancel;
    void             *payload;
    void *          (*function)(void *);
};

void *unless_canceled(void *payload)
{
    struct spec *const spec = (struct spec *)payload;

    /* Make sure the parameters are valid. */
    if (!spec || !spec->lock || !spec->function)
        return NULL;

    /* Grab the lock. */
    if (pthread_mutex_lock(spec->lock))
        return NULL;

    /* Canceled? */
    if (spec->cancel && *(spec->cancel)) {
        pthread_mutex_unlock(spec->lock);
        return NULL;
    }

    pthread_mutex_unlock(spec->lock);

    return spec->function(spec->payload);
}
The way you use the wrapper function is simple:
Code:
pthread_t       thread[2];
struct spec     spec[2];
int             err[2];
pthread_attr_t  attrs;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
int             cancel;

/* Create a pthread attribute to limit stack size to 65536 bytes. */
pthread_attr_init(&attrs);
pthread_attr_setstacksize(&attrs, 65536);

/* Grab the mutex to stop the wrapper scripts. */
pthread_mutex_lock(&lock);

/* Point the work specs to the shared states. */
spec[0].lock = &lock;
spec[1].lock = &lock;
spec[0].cancel = &cancel;
spec[1].cancel = &cancel;

/* Set the worker function and payload. */
spec[0].payload = (void *)c1;
spec[0].function = sender;

spec[1].payload = (void *)c2;
spec[1].function = sender;

/* Create the threads. */
err[0] = pthread_create(&thread[0], &attrs, unless_canceled, &spec[0]);
err[1] = pthread_create(&thread[1], &attrs, unless_canceled, &spec[1]);

if (err[0] || err[1]) {

    /* One or both failed: cancel the threads. */
    cancel = 1;
    pthread_mutex_unlock(&lock);

    /* Reap aborted threads. Mark err[] so you can check later. */
    if (!err[0]) { pthread_join(thread[0], NULL); err[0] = ENOENT; }
    if (!err[1]) { pthread_join(thread[1], NULL); err[1] = ENOENT; }

} else {

    /* Threads created successfully. Let them proceed. */
    cancel = 0;
    pthread_mutex_unlock(&lock);
}

/*
 * Note: At this point, err[0] and err[1] are both zero
 *       iff the threads were created successfully.
 *       Otherwise, both are nonzero errno values, and any
 *       temporarily created thread(s) have been cleaned up.
*/

/* After no further threads will be created, destroy the attributes. */
pthread_attr_destroy(&attrs);
Note that although I use the term cancel above, I do not refer to thread cancellation, which is a mechanism provided by the pthread library. It is just a name I found logical for the wrapper function operation.

Also note how this implementation is quite clean (other than my messy code). There are no global variables, and everything is transparent to the thread functions themselves.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Can we actually create threads in C? aarontwc Programming 6 11-27-2008 08:56 AM
how to create Timer based threads mugdha Programming 5 04-18-2008 09:16 AM
Using system calls to create/context switch threads in assembly code casmac Programming 1 07-13-2007 05:48 PM
How to create more than 2000 threads inlinux 2.4kernel Agnello Programming 5 07-11-2006 10:12 AM
Java threads listed using kill -3 does not contain all threads found using ps -auxww coneheed Programming 2 11-14-2005 09:57 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:40 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration