My Avatar

Shilong ZHAO

Monitor Process Event with Timeout

2017-01-03 00:00:00 +0100

In case you have any questions or suggestions, you can leave comments HERE . Thanks!

Generally speaking, the events in an operating system are either related to file, signal, or process. For a file descriptor, the possible events could be ready to read, write etc; for a signal, the events could be upon reception; for a process, the events could be upon exit, upon calling exec or fork etc.

To monitor file related events with a timeout, there are system calls like select, poll, etc. To monitor signal related events, there are two possible solutions: the easier but non-standard one, use sigtimedwait; or use sigalfd to create file descriptors related with a signal, and then apply select (this could be used to monitor a child process when the signal is set as SIGCHILD).

But to monitor a process with a timeout? There come kqueue and kevent. In fact, they are also able to do the file and signal monitor works, with proper parameters fed to EV_SET macro. For detailed references, click here.

In this post, a code snippet to monitor a process with time out is given (there is not much code examples about process monitoring but a lot about network file descriptors).


 * monitor child process with a time out,
 * using EVFILT_PROC, NOTE_TRACK (deprecated)
 * usage: ./kq2 timeout
 * best ref:
 * other refs:
#include <sys/event.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void diep(const char *s)

long get_time_ms() {
    struct timeval time;
    gettimeofday(&time, NULL);
    long millis = (time.tv_sec * 1000) + (time.tv_usec / 1000);
    return millis;

int main(int argc, char **argv) {
    struct kevent change;
    struct kevent event;
    struct timespec timeout;

    int kq, nev;
    pid_t  pid;

    if (argc != 2)
        return -1;

    int msec = atoi(argv[1]);
    timeout.tv_sec = msec / 1000;
    timeout.tv_nsec = (msec % 1000) * 1000000;

    if ((kq = kqueue()) == -1)

    if ((pid = fork()) < 0)
        diep("fork error");

    if (pid == 0) {
        usleep(7000); // sleep for 7 ms
        if (execlp("date", "date", (char *)0) < 0)
            diep("execlp date error");
    else {
        long start_time = get_time_ms();
        // try with NOTE_EXIT, NOTE_TRACK, NOTE_EXEC, etc.
        EV_SET(&change, pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0,0);
        nev = kevent(kq, &change, 1, &event, 1, &timeout);
        long end_time = get_time_ms();
        if (nev < 0) {
            diep("nev error");
        if (nev == 0) {
            diep("no event");
        if (nev > 0) {
            printf("nev = %d, time = %ld milliseconds\n", nev, end_time - start_time);
            return 0;
    return EXIT_SUCCESS;