【发布时间】:2020-03-23 18:30:32
【问题描述】:
所以阅读this topic,常见的退出方式是使用标志。我的问题是,如何处理等待?假设线程仅每 30 秒运行一次,您将如何正确等待这 30 秒?
使用sem_timedwait() 并不理想,因为它依赖于系统时钟,对时钟的任何更改都会严重影响您的应用程序。 This topic 解释使用条件变量。问题是,它依赖于互斥体。您不能在信号处理程序中安全地使用pthread_mutex_lock() 和pthread_mutex_unlock()。所以就我上面 30 年代的例子来说,如果你想立即退出,谁在处理互斥锁解锁?
我的猜测是另一个线程,其唯一目的是检查退出标志,如果为真,它将解锁互斥锁。但是,那条线是什么样的?只是坐在那里不断检查旗帜不是浪费资源吗?例如,您会使用sleep() 并检查每1 秒吗?
我不相信我的猜测是正确的。这似乎非常低效,我遇到了类似的“我该如何等待”类型的问题。我觉得我错过了一些东西,但我的搜索导致的主题类似于我链接的关于标志的内容,但没有等待。
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <unistd.h>
pthread_mutex_t my_mutex;
volatile sig_atomic_t exitRequested = 0;
void signal_handler(int signum) {
exitRequested = 1;
}
bool my_timedwait(pthread_mutex_t *mutex, int seconds) {
pthread_condattr_t attr;
pthread_condattr_init(&attr);
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
pthread_cond_t cond;
pthread_cond_init(&cond, &attr);
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
ts.tv_sec += seconds;
int status = pthread_cond_timedwait(&cond, mutex, &ts);
if (status == 0) {
return false; // mutex unlocked
}
if ((status < 0) && (status != ETIMEDOUT)) {
// error, do something
return false;
}
return true; // timedout
}
void *exitThread(void *ptr) {
// constant check???
while (1) {
if (exitRequested) {
pthread_mutex_unlock(&my_mutex);
break;
}
}
}
void *myThread(void *ptr) {
while (1) {
// do work
printf("test\n");
// wait and check for exit (how?)
if (!my_timedwait(&my_mutex, 30)) {
// exiting
break;
}
}
}
int main(void) {
// init and setup signals
struct sigaction sa;
sa.sa_handler = signal_handler;
sigaction(SIGINT, &sa, NULL);
// init the mutex and lock it
pthread_mutex_init(&my_mutex, NULL);
pthread_mutex_lock(&my_mutex);
// start exit thread
pthread_t exitHandler;
pthread_create(&exitHandler, NULL, exitThread, NULL);
// start thread
pthread_t threadHandler;
pthread_create(&threadHandler, NULL, myThread, NULL);
// wait for thread to exit
pthread_join(threadHandler, NULL);
pthread_join(exitHandler, NULL);
return EXIT_SUCCESS;
}
【问题讨论】:
-
信号处理程序与什么有什么关系?为什么要在信号处理程序中等待。使用
pthread_cond_timewait将是执行此操作的典型方法。 -
您能否提供一些代码来说明您正在尝试做的事情,并描述为什么您尝试的方法不起作用?
-
@DavidSchwartz 一切?问题是如何等待退出条件。例如,当您按 Ctrl+C 时,如何将其传递给线程。当使用
pthread_cond_timewait时,它需要一个互斥锁,并且您不能在信号处理程序中使用互斥锁。 -
@jxh 确定我可以添加代码,但我不确定它如何帮助解决这个问题。问题不在于我所拥有的东西不起作用。就是我概述的内容不是很有效,而且看起来也不合适。我会添加一些代码。它基本上是编码的最后两段。
-
@F.Coz 如果您需要在多线程程序中处理外部信号,那么在除一个线程之外的所有线程中阻塞这些信号并拥有一个线程来等待信号是绝对值得的。这样,您就不需要信号处理程序了。
标签: c multithreading pthreads