signal的samplecode
一个signal的samplecode, 需要注意的地方是:
- 资源的释放和析构
- 锁的控制
- 资源的清理
- 事务的控制
/* 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; } } }

浙公网安备 33010602011771号