0
int main()
{
    pthread_t thread;
    int a = 0;

    while(a == 0)
    {
        accept(...); //accept a new connection (blocking)
        pthread_create(&thread, NULL, threaded_function, &a);
    }
    pthread_join(...);
    return 0;
}

My goal is to keep the main thread looping until a thread returns with a not equal to zero. The problem is that pthread_create isn't returning a value. I'm guessing this is because the main thread isn't waiting at pthread_join, but instead is in a loop waiting at accept. But if I join the threads inside of the loop, the loop won't be running. Is the only way of accomplishing this by creating another thread, and another threaded function just to watch the value of a?

Michael Blake
  • 993
  • 1
  • 8
  • 18
  • 2
    Thread synchronization is done with condition variables, would they work for you: https://stackoverflow.com/questions/8901538/synchronize-threads-for-pthread-cond-broadcast-call – mnistic Nov 01 '17 at 00:52
  • I forgot about condition variables. I'll have to see if I can restructure my code to use them. Hopefully that'll do the trick. – Michael Blake Nov 01 '17 at 01:18
  • Looking at this again, I don't know if condition variables will work because `wait` will block any threads, including the main thread that needs to keep looping. Is there any way of using a signal to inform the loop that it can stop looping and exit? – Michael Blake Nov 01 '17 at 02:20
  • I'm a little confused. Your main thread is stuck in accept. Is your goal to somehow break out of accept based on what happens in another thread? – mnistic Nov 01 '17 at 02:30
  • My main thread is stuck in accept unless a new connection is established, then it makes a new thread, and loops back around to accept and waits. If anything happens within `threaded_function` that sets `a` to zero, I just want the program to end (and the threads to exit) once that thread returns. – Michael Blake Nov 01 '17 at 02:34

1 Answers1

1

Your problem is that your main thread is stuck in accept which is a blocking call, so to make it break out of it it would probably be best to send a signal which will cause an interrupt. IIRC something like this should work. In your worker thread:

void* sthread(void* p)
{
  int* keep_running = (int*)p;
  sigset_t set;
  sigemptyset(&set);
  sigaddset(&set, SIGTERM);
  pthread_sigmask(SIG_BLOCK, &set, NULL);
  sleep(5);
  *keep_running = 0;
  pthread_kill(main_threadId, SIGTERM);
}

And then in your main thread:

struct sigaction sa;
int keep_running = 1;
...
main_threadId = pthread_self();
sa.sa_handler = signal_handler; //This can be just an empty function
sigaction(SIGTERM, &sa, NULL);
...
while(keep_running)
{
    sock = accept(sock_desc, (struct sockaddr *)&client, (socklen_t*)&c);
    pthread_create(&thread, NULL, sthread, &keep_running);
}
close(sock);

This will allow you to close the socket cleanly and tidy up. Of course, you will probably want to have more than one socket so you will have to manage them in an array or somehow else.

mnistic
  • 10,866
  • 2
  • 19
  • 33