ant2009
ant2009

Reputation: 22486

processing pthread for clean exit

linux gcc c89

Currently I have an event loop that will capture and process events. This event loop will run in its own thread that is created from the main function. For testing purposes I am using a usleep in this loop.

I have a condition app_running to control the loop and exit the loop.

However, when I run my application I don't want to exit main because that will terminate the application. So I have a put a getchar() to wait for an input to indicate that I want to terminate the application. That will set the app_running to false to exit the event loop. This all looks a bit cheap. Is there a better way to do this without using the getchar()?

Many thanks for any suggestions,

Header

#ifndef NETWORK_TASKS_H_INCLUDED
#define NETWORK_TASKS_H_INCLUDED

#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE (!FALSE)
#endif

int app_running;

void* process_events(void);

#endif /* NETWORK_TASKS_H_INCLUDED */

Implemenation

#include <stdio.h>
#include <unistd.h>

#include "network_tasks.h"

void* process_events(void)
{
    app_running = TRUE;

    while(app_running) {
#define TIMEOUT 3000000
        /* This will be used for capturing events. use usleep for simulating testing */
        /* if(net_events(TIMEOUT) != 0) { */
        /*     process_network_event(); */
        /* } */
        /* Just for testing */
        usleep(TIMEOUT);
        printf("Sleeping.....\n");
    }

    printf("Finished sleeping....\n");

    return NULL;
}

main

#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>

#include "network_tasks.h"

int main(void)
{
    pthread_t th_id = 0;
    int th_rc = 0;

    th_rc = pthread_create(&th_id, NULL, (void*)process_events, NULL);

    if(th_rc == -1) {
        fprintf(stderr, "Cannot create thread [ %s ]\n", strerror(errno));
        return -1;
    }

    getchar();
    app_running = FALSE;

    pthread_exit(NULL);

    return 0;
}

Upvotes: 0

Views: 6744

Answers (2)

Duck
Duck

Reputation: 27542

If you have some other mechanism to indicate the end of the program and the only reason you are using getchar() is to block so you don't end the program then you don't need it at all.

You can pthread_join() the process thread in main. Main will block on that call until the process thread finishes.

Alternatively, if you have no further work to do in main anyway, you can simply pthread_exit(). Unlike exit(), pthread_exit() will not kill all other running threads.

Also, you have coded the return code check of pthread_create() incorrectly. Pthreads departs from the standard unix return code of -1 on error convention. It returns 0 on success and a positive integer code on error.

int main(void)
{
    pthread_t th_id;
    int th_rc;

    th_rc = pthread_create(&th_id, NULL, (void*)process_events, NULL);

    if(th_rc != 0) 
    {
        fprintf(stderr, "Cannot create thread [ %s ]\n", strerror(th_rc));
        return -1;
    }

    th_rc = pthread_join(th_id, NULL);

    return 0;
}

Upvotes: 3

Pete Wilson
Pete Wilson

Reputation: 8694

That's the way to do it. If you'd rather not block waiting for getchar( ) to return, you can use the linux version of kbhit( ):

http://pwilson.net/kbhit.html

Upvotes: 1

Related Questions