Showing posts with label daemon. Show all posts
Showing posts with label daemon. Show all posts

Posix Queue De-queuer/Consumer in C++

Last post we read about daemon, which posting message in queue. In this post we write code about consumer who consume those messages. you can use daemon as consumer( look daemon code). we need to use signal processing and mq_notify from posix mqueue. we used old mqueue routines from old post(Posix queue)
Consumer application.

int main() { update_notification(); while(1) pause(); }

Used Code

#include <signal.h>
/* Thread start function */
static void my_sig_handler(union sigval sv) { mqd_t mqid = *((mqd_t *) sv.sival_ptr); std::string strmsg; while(get_message(mqid,strmsg)){ cout<<"Message : "<<strmsg<<endl; } update_notification(mqid);
// re-registor notification
}


void update_notification(mqd_t& mqid) { struct sigevent sigev1;
// For notification
sigev1.sigev_notify = SIGEV_THREAD; sigev1.sigev_notify_function = my_sig_handler; sigev1.sigev_notify_attributes = NULL; sigev1.sigev_value.sival_ptr = &mqid;
/* Arg. to thread func. */
if (mq_notify (mqid, &sigev1) == -1) { if (errno == EBUSY) printf ("Another process has registered for notification.\n"); perror("Error:mq_notify: "); _exit (EXIT_FAILURE); } }


Daemon in C++

Steps for daemon.

  1. fork child process.
  2. if child fork success, exit parent.
  3. umask file permission for child.
  4. set session id or attach with init process.
  5. change current working dirctory.
  6. close standard file descriptors.
  7. start daemon work initilization.
  8. run daemon loop.
  9. handle signals for terminating( we will see next blog).
Sample code daemon loop used Posix Queue toen-queuemessages from old post.
Sample code

void run_daemon() { fork_child(); initchild(); run_daemon(); exit(EXIT_SUCCESS); }

Function used in sample

void fork_child() { pid_t sid;
// fork off the parent process
pid = fork();
// return -1 if failed
if (pid < 0) { exit(EXIT_FAILURE); }
// If we got PID, then exit the parent process.
if (pid > 0) { exit(EXIT_SUCCESS); } } void initchild() { pid_t sid
// set the file mask.
umask(0);
// open log file here for logging.
// set session id for child process.
sid = setsid(); if (sid < 0) { exit(EXIT_FAILURE); }
// change the current working directory
if ((chdir("/")) < 0) { exit(EXIT_FAILURE); }
// close standard file descriptors
close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); }

Main daemon loop

void daemon_loop() {
// daemon-specific initialization
mqd_t mqid; if(open_queue(mqid)){
// daemon loop
while (1) {
// daemon work
send_message(mqid,"This message from daemon",64); sleep(1); // wait } close_queue(mqid); } }