简体   繁体   English

在cpp中使用pthread_mutex_t

[英]Using pthread_mutex_t in cpp

In my program I have a daemon thread that waits for tasks and print them to a file. 在我的程序中,我有一个守护程序线程,它等待任务并将其打印到文件中。 Its function is: 其功能是:

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;
}

So as you can see the when there are no pending task the daemon waits for new ones. 因此,如您所见,当没有挂起的任务时,守护程序将等待新的任务。 When I get a new one I push it to a data base in a different class (daemon is not in a class) and then send a signal as follows: 当我得到一个新的数据库时,我将其推送到另一个类的数据库中(守护程序不在一个类中),然后发送如下信号:

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);
}

Three questions: 三个问题:

  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? 从此处的代码尚不清楚,但是daemon()pushNewTask()使用相同的pthread_mutex_t对象-这不是问题吗? When daemon goes to sleep (wait) it doesn't unlock the mutex. 当守护程序进入睡眠状态(等待)时,它不会解锁互斥锁。
  2. What is the meaning that several functions are locked with the same pthread_mutex_lock ? 用同一个pthread_mutex_lock锁定几个函数的含义是什么? Maybe that only one thread can access either of them? 也许只有一个线程可以访问它们中的任何一个? When should I use different pthread_mutex_t objects ? 什么时候应该使用其他pthread_mutex_t objects

Thanks 谢谢

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? 1:从此处的代码尚不清楚,但是daemon()和pushNewTask()都使用相同的pthread_mutex_t对象-这不是问题吗?

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

No this is not a problem. 不,这不是问题。 The call to pthread_cond_wait() releases the lock and suspends the thread. 调用pthread_cond_wait()会释放锁并挂起线程。 When the condition variable is signaled. 当发出条件变量时。 The thread re-aquires the lock and then returns from the call to pthread_cond_wait() . 线程重新获取锁 ,然后从调用返回到pthread_cond_wait() So while the thread is running it will have the lock and while it is asleep the lock is released (note if another thread is holding the lock on the mutext the thread can not exit pthread_cond_wait() ). 因此,当线程正在运行时,它将拥有该锁,而当其处于睡眠状态时,该锁将被释放(请注意,如果另一个线程在mutext上持有该锁,则该线程无法退出pthread_cond_wait() )。

2: What is the meaning that several functions are locked with the same pthread_mutex_lock? 2:使用同一pthread_mutex_lock锁定多个函数是什么意思? Maybe that only one thread can access either of them? 也许只有一个线程可以访问它们中的任何一个? When should I use different pthread_mutex_t objects? 什么时候应该使用其他pthread_mutex_t对象?

No. You should always use the same mutex/condition variable pair. 不能。您应该始终使用相同的互斥/条件变量对。 Also access to an object (in this case the Manager object) is usually controlled by a single lock. 同样,对对象(在这种情况下为Manager对象)的访问通常由单个锁控制。 This means that only the thread holding the lock can execute code in the manager object (thus only one thread at a time). 这意味着只有持有锁的线程才能在管理器对象中执行代码(因此一次仅一个线程)。 Threads suspended on a 'condition variable` release the lock so other threads can work while they are suspended but must re-aquire the lock before they are allowed to execute code in the manager. 挂在“条件变量”上的线程会释放该锁,以便其他线程在挂起时可以工作,但必须重新获取该锁,然后才能在管理器中执行代码。

Better usage: 更好的用法:

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

This is highly susceptible to race conditions. 这非常容易受到比赛条件的影响。 It should be written like this: 应该这样写:

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

see: Thread Wait For Parent 请参阅: 线程等待父对象

Error: 错误:

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

This is a problem. 这是个问题。 The thread is dying while still holding a lock on the mutex. 线程快死了,同时仍然保持互斥锁。 Before the thread dies it should release the mutex. 在线程死亡之前,应释放互斥体。 Preferablly the mutex should be controlled via RAII so that its usage is exception safe and you can exit the thread by returning from the function rather than call pthread_exit(). 互斥锁最好通过RAII进行控制,这样它的使用是异常安全的,您可以通过从函数返回而不是调用pthread_exit()退出线程。

Using pthread_exit() is like calling exit() in a normal application. 使用pthread_exit()就像在普通应用程序中调用exit()一样。 This is not a good idea as automatic objects on the stack are not correctly destroyed. 这不是一个好主意,因为堆栈中的自动对象未正确销毁。 This can be a problem in C++ code thus the use of pthread_exit() is discouraged, instead you should let the thread die naturally by allowing it to return from the original function that initiated it. 这在C ++代码中可能是一个问题,因此不鼓励使用pthread_exit(),而是应该允许线程从启动它的原始函数返回,从而自然地使线程死亡。 (PS do not throw an exception that unwinds a thread stack to the end. What pthreads does when a thread exits because of an exception is undefined (most systems I have seen this causes the application to terminate)). (PS不会抛出将线程堆栈释放到末尾的异常。由于异常而导致线程退出时pthreads的作用是不确定的(我见过的大多数系统都会导致应用程序终止)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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