「ライブラリに関する警告」を増やすことなく、シグナルを使用できると思います。次の点を考慮してください。
#include <pthread.h>
#include <signal.h>
#include <stddef.h>
static pthread_t thread;
static volatile sig_atomic_t sigCount;
/**
* Executes a concurrent task. Called by `pthread_create()`..
*/
static void* startTask(void* arg)
{
for (;;) {
// calls to `select()`, `accept()`, `read()`, etc.
}
return NULL;
}
/**
* Starts concurrent task. Doesn't return until the task completes.
*/
void start()
{
(void)pthread_create(&thread, NULL, startTask, NULL);
(void)pthread_join(thread);
}
static void noop(const int sig)
{
sigCount++;
}
/**
* Stops concurrent task. Causes `start()` to return.
*/
void stop()
{
struct sigaction oldAction;
struct sigaction newAction;
(void)sigemptyset(&newAction.sa_mask);
newAction.sa_flags = 0;
newAction.sa_handler = noop;
(void)sigaction(SIGTERM, &newAction, &oldAction);
(void)pthread_kill(thread, SIGTERM); // system calls return with EINTR
(void)sigaction(SIGTERM, &oldAction, NULL); // restores previous handling
if (sigCount > 1) // externally-generated SIGTERM was received
oldAction.sa_handler(SIGTERM); // call previous handler
sigCount = 0;
}
これには次の利点があります。
- 通常の EINTR 処理以外に、タスク コードに特別なことは必要ありません。
pthread_cancel()
その結果、 、pthread_cleanup_push()
、pthread_cleanup_pop()
、およびを使用するよりも、リソースのリークに関する推論が容易になりpthread_setcancelstate()
ます。
- 追加のリソース (パイプなど) は必要ありません。
- 複数の同時タスクをサポートするように拡張できます。
- それはかなりボイラープレートです。
- コンパイルさえできるかもしれません。:-)