[英]sem_post does not prioritise sem_wait call in other thread
I am working on my project where it is crucial that everything is cleaned up properly and all buffered log messages are saved to a file etc.. I am calling exit from another thread and I was thinking to use a semaphore to wait for the cleanup in main thread to occur before the program fully exits. 我正在我的项目中,至关重要的一点是必须正确清理所有内容并将所有缓冲的日志消息保存到文件等。我正在调用另一个线程的出口,并且我正考虑使用信号量来等待清理主线程在程序完全退出之前发生。 The problem is that when I call sem_post from my exit handler registred with atexit, sem_wait will not immediately decrement the semaphore thus sem_wait in my exit handler will exit immediately because the semaphore is greater than zero. 问题是,当我从注册了atexit的退出处理程序中调用sem_post时,sem_wait不会立即减小信号量,因此,由于信号量大于零,因此我的退出处理程序中的sem_wait将立即退出。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>
static sem_t sem;
void *do_work(void *arg) {
// if something fails
printf("Something failed!\n");
exit(1);
}
void exit_handler() {
sem_post(&sem); // wake up main thread
sem_wait(&sem); // wait for cleanup in main
sem_destroy(&sem);
}
int main() {
pthread_t worker_thread;
sem_init(&sem, 0, 0);
atexit(exit_handler);
pthread_create(&worker_thread, NULL, do_work, NULL);
sem_wait(&sem); // block this thread until work is done
// simulate some cleanup
usleep(1000000);
printf("This never gets called!\n");
sem_post(&sem); // destroy semaphore
}
This example demonstrates my problem. 这个例子说明了我的问题。 Is there any solution to this problem? 有什么解决办法吗? I mustn't put the cleanup in my exit handler because I have a lot of local resources in the main function that needs to be cleaned up in my actual program. 我不能将清理工作放在退出处理程序中,因为主要功能中有很多本地资源需要在我的实际程序中进行清理。
You can't control which thread will return from sem_wait()
after a call to sem_post()
. 在调用sem_post()
之后,您无法控制哪个线程将从sem_wait()
返回。 You need to use two semaphores: 您需要使用两个信号量:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>
static sem_t wakeupMain;
static sem_t cleanupDone;
void *do_work(void *arg) {
// if something fails
printf("Something failed!\n");
exit(1);
}
void exit_handler() {
sem_post(&wakeupMain); // wake up main thread
sem_wait(&cleanupDone); // wait for cleanup in main
sem_destroy(&wakeupMain);
sem_destroy(&cleanupDone);
}
int main() {
pthread_t worker_thread;
sem_init(&wakeupMain, 0, 0);
sem_init(&cleanupDone, 0, 0);
atexit(exit_handler);
pthread_create(&worker_thread, NULL, do_work, NULL);
sem_wait(&wakeupMain); // block this thread until work is done
// simulate some cleanup
usleep(1000000);
printf("This never gets called!\n");
sem_post(&cleanupDone); // destroy semaphore
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.