gpt4 book ai didi

c++ - 在 cpp 中使用 pthread_mutex_t

转载 作者:行者123 更新时间:2023-11-28 00:57:05 24 4
gpt4 key购买 nike

在我的程序中,我有一个守护线程等待任务并将它们打印到文件中。它的作用是:

void * deamon(void *) {
while(true) {
pthread_mutex_lock(manager->getLock());
while(!manager->isPending()) {
if (manager->isClosing()) {
pthread_exit(NULL);
}
pthread_cond_wait(manager->getCond(), manager->getLock());
//check that condition if met - surprises may occur!
}
//WRITE TO FILE HERE
pthread_mutex_unlock(manager->getLock());
}
return NULL;
}

因此,正如您所见,当没有待处理任务时,守护进程会等待新任务。当我得到一个新的时,我将它推送到另一个类中的数据库(守护进程不在一个类中),然后发送一个信号如下:

void Manager::pushNewTask(Task * task) {
pthread_mutex_lock(_lock);
map<int,Task *>::iterator it = _tasks->end();
_tasks->insert(it,make_pair(task->getId(),task));
// At the first time a signal is sent with no need
if (_tasks->size() == 1) {
_pending = true;
pthread_cond_signal(_cond); //SEND SIGNAL TO DAEMON THREAD
}
pthread_mutex_unlock(_lock);
}

三个问题:

  1. 从这里的代码看不清楚,但是 daemon()pushNewTask() 使用相同的 pthread_mutex_t 对象 - 这不是一个问题?当守护进程进入休眠状态(等待)时,它不会解锁互斥量。
  2. 几个函数被同一个pthread_mutex_lock锁定是什么意思?也许只有一个线程可以访问它们中的任何一个?什么时候应该使用不同的 pthread_mutex_t 对象

谢谢

最佳答案

1: Its not clear from the code here but both daemon() and pushNewTask() use the same pthread_mutex_t object - is that not a problem?

pthread_cond_wait(manager->getCond(), manager->getLock());

不,这不是问题。调用 pthread_cond_wait() 释放锁并挂起线程。当条件变量发出信号时。线程重新获取锁,然后从对pthread_cond_wait() 的调用返回。因此,当线程正在运行时,它将拥有锁,而当它处于休眠状态时,锁将被释放(请注意,如果另一个线程持有互斥体上的锁,则该线程无法退出 pthread_cond_wait())。

2: What is the meaning that several functions are locked with the same pthread_mutex_lock? Maybe that only one thread can access either of them? When should I use different pthread_mutex_t objects?

没有。您应该始终使用相同的互斥锁/条件变量对。此外,对对象(在本例中为 Manager 对象)的访问通常由单个锁控制。这意味着只有持有锁的线程才能执行管理器对象中的代码(因此一次只能有一个线程)。在“条件变量”上挂起的线程释放锁,以便其他线程可以在挂起时工作,但必须重新获取锁才能在管理器中执行代码。

更好的用法:

pthread_cond_wait(manager->getCond(), manager->getLock());

这很容易受到竞争条件的影响。应该这样写:

while(<No Tasks available>)
{
pthread_cond_wait(manager->getCond(), manager->getLock());
}

参见:Thread Wait For Parent

错误:

        if (manager->isClosing()) {
pthread_exit(NULL);
}

这是一个问题。线程正在死亡,同时仍然持有互斥体上的锁。在线程死亡之前,它应该释放互斥体。最好通过 RAII 控制互斥量,这样它的使用是异常安全的,并且您可以通过从函数返回而不是调用 pthread_exit() 来退出线程。

使用 pthread_exit() 就像在普通应用程序中调用 exit() 一样。这不是一个好主意,因为堆栈上的自动对象没有被正确销毁。这在 C++ 代码中可能是一个问题,因此不鼓励使用 pthread_exit(),相反,您应该允许线程从启动它的原始函数返回,从而让线程自然死亡。 (PS 不会抛出将线程堆栈展开到末尾的异常。当线程因异常退出时 pthreads 会做什么是未定义的(我见过的大多数系统都会导致应用程序终止)。

关于c++ - 在 cpp 中使用 pthread_mutex_t,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10486258/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com