簡體   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