繁体   English   中英

sem_post不在其他线程中优先处理sem_wait调用

[英]sem_post does not prioritise sem_wait call in other thread

我正在我的项目中,至关重要的一点是必须正确清理所有内容并将所有缓冲的日志消息保存到文件等。我正在调用另一个线程的出口,并且我正考虑使用信号量来等待清理主线程在程序完全退出之前发生。 问题是,当我从注册了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
}

这个例子说明了我的问题。 有什么解决办法吗? 我不能将清理工作放在退出处理程序中,因为主要功能中有很多本地资源需要在我的实际程序中进行清理。

在调用sem_post()之后,您无法控制哪个线程将从sem_wait()返回。 您需要使用两个信号量:

#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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM