1

currently I am doing.

int main()
{
  create_daemon_thread_and_run();

  getchar();
  return 0;
}

I use a getchar() to block main thread terminate entire process.

I don't like getchar() because if I type something to stdin, it will return and process will terminate. But I want it block forever, something like

while()
{
  ;
}

But I have concern while loop forever will eat up CPU useage. I want something just put the thread resting, and don't eat CPU. And I want cross-platform way to do so.

Jherico
  • 28,584
  • 8
  • 61
  • 87
Helin Wang
  • 4,002
  • 1
  • 30
  • 34
  • 4
    If we knew your requirements maybe. – Nikos C. Nov 18 '12 at 00:38
  • `#define waitForInput getchar` – Chris Eberle Nov 18 '12 at 00:39
  • There's never a good reason to simply block the main thread. You need to specify what condition you're waiting to satisfy in order for the thread to continue. If you specify what that condition is you'll get a sane answer. – Jherico Nov 18 '12 at 00:46
  • Either wait for the thread you created to exit by joining it or just exit your current thread letting the daemon thread go on about its business. Without knowing how you're creating threads and what threading library/model you're using, we can't tell you specifically. – David Schwartz Nov 18 '12 at 00:56
  • while loop with sleep should release cpu usage to 0%, but not good solution – billz Nov 18 '12 at 00:58
  • @billz +1 for simplicity – Helin Wang Nov 18 '12 at 01:02

3 Answers3

3

You can simply wait for your thread to finish, thread.join will block main thread till your spawned thread to finish. But you don't detach your thread to daemon.

If you can get some sort of state flag from create_daemon_thread_and_run();, it will be much easier

int main()
{
  bool is_thread_finished = false;
  create_daemon_thread_and_run(is_thread_finished);
  while (!is_thread_finished){
    sleep(1);
  }
  return 0;
}

C++11 demo:

#include <thread>
void thread_function()
{
    // do something in a loop
}

int main()
{
  std::thread t1(thread_function);   
  t1.join();

  return 0;
}
billz
  • 44,644
  • 9
  • 83
  • 100
  • not exactly, the compiler I am using does not support c++11. But if you have a c++11 solution I would also like to know:) – Helin Wang Nov 18 '12 at 00:50
  • thank you. This is a reasonable approach. One thing I want to point out is sometimes daemon is from a third party library, and will return immediately after calling it. So in this case your solution does not work. – Helin Wang Nov 18 '12 at 00:59
  • And the 3rd party lib is cross-platform? – billz Nov 18 '12 at 01:00
  • If your create_daemon_thread_and_run can take some status flag, things will be easier, see my updated sample. – billz Nov 18 '12 at 01:07
2

You'd probably be better of using pthread_join (if it was a pthread, non-detached thread).

Otherwise, use a mutex, condition variable, or sempahore.

The following sample demonstrates how to use a semaphore, and it responds to signals (e.g. when Ctrl-C is used in the terminal). Of course, your 'demon' implementations is free to signal the semaphore when it's done processing and wants to shut down.

#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <semaphore.h>

static sem_t daemon_shutdown;

static void exit_handler(int sig) {
    sem_post(&daemon_shutdown);
}

static int set_signal_handler(int sig, void (*handler)(int)) {
    struct sigaction sa;
    memset(&sa, 0, sizeof(struct sigaction));
    sa.sa_handler = handler;
    sigemptyset(&(sa.sa_mask));
    sa.sa_flags = 0;
    if(sigaction(sig, &sa, NULL) == -1) {
        perror("sigaction");
        return -1;
    }
    return 0;
}

// DEFINE THESE FOR YOUR PROGRAM:
int do_daemon();
void do_exit();
//

int main() {
    assert(0 == sem_init(&daemon_shutdown, 0, 0));
    if(!do_daemon()) {
        do_exit();
        return 1;
    }
    if(
        set_signal_handler(SIGHUP, exit_handler) != 0 ||
        set_signal_handler(SIGINT, exit_handler) != 0 ||
        set_signal_handler(SIGTERM, exit_handler) != 0 ||
        set_signal_handler(SIGPIPE, SIG_IGN) != 0) {
        do_exit();
        return 2;
    }
    sem_wait(&daemon_shutdown);
    do_exit();
    return 0;
}
sehe
  • 374,641
  • 47
  • 450
  • 633
  • thank you. What I want to comment is spin lock is busy waiting, still eat CPU time. conditional variable or semaphore is very reasonable approach. Thanks for pointing out signals. More on locks: http://stackoverflow.com/questions/3513045/conditional-variable-vs-semaphore http://stackoverflow.com/questions/195853/spinlock-versus-semaphore – Helin Wang Nov 18 '12 at 00:56
  • I was trying to use this, but I get: `fatal error C1083: Cannot open include file: 'semaphore.h': No such file or directory`. Does is `semaphore` an opensource library or something like that? – Alexander Leon VI Nov 20 '15 at 16:16
-1

What does your program do?

If the background threads are performing some sort of calculation, etc, then your main thread should be waiting for the background threads to complete. If you are using windows, see CreateEvent and WaitForMultipleObjects.

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328