signal的samplecode

一个signal的samplecode, 需要注意的地方是:

  1. 资源的释放和析构
  2. 锁的控制
  3. 资源的清理
  4. 事务的控制

 

/* This is signal handler common code */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <iostream>
#include <vector>
#include <atomic>
#include <csignal>
#include <thread>

volatile std::atomic_bool g_bExitFlag{false};
volatile std::atomic_bool g_bInitFlag{false};

constexpr uint8_t kNumOfThreads = 5;
std::vector<std::thread> gThreads;

void SignalHandlerThread(void) {
	int sig = -1;
	sigset_t sigset;

	if (sigemptyset(&sigset) != 0) {
		/* empty the set of signals */
		printf("Emptying signal set failed.");
		return;
	}

	if (sigaddset(&sigset, SIGTERM) != 0) {
        /* add SIGTERM to signal set */
		printf("Adding SIGTERM to signal set failed.");
		return;
	}

	if (sigaddset(&sigset, SIGINT) != 0) {
        /* add SIGINT to signal set */
		printf("Adding SIGINT to signal set failed.");
		return;
	}

	/* wait until signal SIGTERM/SIGINT occurs */
	while (sig != SIGTERM && sig != SIGINT) {
		if (0 != sigwait(&sigset, &sig)) {
			printf("Sigwait() was called with an invalid signal set.");
			return;
		}
	}

    printf("SignalHandler get the signal(%d)\n", sig);
	g_bExitFlag = true;
}

int SetSignalMask() 
{
	bool success = true;
	sigset_t signals;

	/* Block all signals except SIGABRT, SIGBUS, SIGFPE, SIGILL and SIGSEGV */
	success = success && (sigfillset(&signals) == 0);
	success = success && (sigdelset(&signals, SIGABRT) == 0);
	success = success && (sigdelset(&signals, SIGBUS) == 0);
	success = success && (sigdelset(&signals, SIGFPE) == 0);
	success = success && (sigdelset(&signals, SIGILL)) == 0;
	success = success && (sigdelset(&signals, SIGSEGV) == 0);
	success = success && (pthread_sigmask(SIG_SETMASK, &signals, nullptr) == 0);
	if (!success) {
		printf("SetSignalMask failed. \n");
        return -1;
	}

    return 0;
}

int Init()
{
	/* initialize signal handling */
	SetSignalMask();

	/* spawn a new signal handler thread */
	gThreads.push_back(std::thread(SignalHandlerThread));
    g_bInitFlag = true;
    
    //printf("tid thtread id    :%lu. \n", gThreads.begin()->get_id());
    printf("tid native handle :%lu. \n", static_cast<pthread_t>(gThreads.begin()->native_handle()));

    return 0;
}

void Shutdown()
{
    /* check state */
	/* clean-up */
    /* kill/cancel pthread */

    /* wait pthread */
	printf("Waitfor the threads.\n");
	for (std::vector<std::thread>::iterator it = gThreads.begin();
			it != gThreads.end(); it++) {
		it->join();
	}

	std::cout << "Terminating." << std::endl;
}

int Run()
{
    Init();
    while (!g_bExitFlag) {
        /* Todo:work thread */
    }

    Shutdown();
    return 0;
}

int main() {
    try {
        Run();
    } catch (std::runtime_error& e) {
        std::cout << "Runtime error: " << e.what();
    } catch (std::logic_error& e) {
        std::cout << "Logic error: "<< e.what();
    } catch (std::exception& e) {
        std::cout << "Exception: "<< e.what();
    } catch (...) {
        std::cout << "Unknown exception";
    }

    return 0;
}

 

/* like pause() */
void HandleSignals()  {
  sigset_t sigset;
  int signal = 0;
  bool done = false;

  ::sigemptyset(&sigset);
  ::sigaddset(&sigset, SIGTERM);
  ::sigaddset(&sigset, SIGINT);
while (!done) {
    timespec timeout;
    timeout.tv_sec = 1;
    timeout.tv_nsec = 0;
    signal = ::sigtimedwait(&sigset, NULL, &timeout);

    switch (signal) {
      case SIGINT:
        printf("call signal SIGINT");
        done = true;
        break;
      case SIGTERM:
        printf("call signal SIGTERM");
        done = true;
        break;
    }
  }
}

 

posted @ 2023-07-24 15:50  sciapex  阅读(10)  评论(0编辑  收藏  举报