Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在cpp中使用pthread\u mutex\t_C++_Locking_Pthreads_Mutex - Fatal编程技术网

C++ 在cpp中使用pthread\u mutex\t

C++ 在cpp中使用pthread\u mutex\t,c++,locking,pthreads,mutex,C++,Locking,Pthreads,Mutex,在我的程序中,我有一个守护进程线程,它等待任务并将它们打印到文件中。 其功能是: void * deamon(void *) { while(true) { pthread_mutex_lock(manager->getLock()); while(!manager->isPending()) { if (manager->isClosing()) { pthread_exit(NU

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

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);
}
void管理器::pushNewTask(任务*Task){
pthread_mutex_lock(_lock);
迭代器it=\u任务->结束();
_任务->插入(it,make_pair(任务->getId(),任务));
//在第一次发送信号时,无需
如果(_tasks->size()==1){
_待定=真;
pthread_cond_signal(_cond);//向守护进程线程发送信号
}
pthread_mutex_unlock(_lock);
}
三个问题:

  • 这里的代码不清楚,但是
    daemon()
    pushNewTask()
    都使用相同的
    pthread\u mutex\u t
    对象-这不是问题吗?当守护进程进入睡眠(等待)状态时,它不会解锁互斥锁
  • 使用相同的
    pthread\u mutex\u lock
    锁定多个函数是什么意思?也许只有一个线程可以访问它们中的任何一个?什么时候应该使用不同的
    pthread\u mutex\u t对象
  • 谢谢

    1:这里的代码不清楚,但daemon()和pushNewTask()都使用相同的pthread\u mutex\t对象-这不是问题吗

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

    2:使用相同的pthread\u mutex\u锁锁定多个函数是什么意思?也许只有一个线程可以访问它们中的任何一个?什么时候应该使用不同的pthread\u mutex\t对象

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

    更好的使用: 这很容易受到比赛条件的影响。应该这样写:

    while(<No Tasks available>)
    {
        pthread_cond_wait(manager->getCond(), manager->getLock());
    }
    
    这是一个问题。线程正在消亡,同时仍保持互斥锁。在线程死亡之前,它应该释放互斥锁。最好通过RAII控制互斥体,这样它的使用是异常安全的,您可以通过从函数返回而不是调用pthread_exit()退出线程

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

    1:这里的代码不清楚,但daemon()和pushNewTask()都使用相同的pthread\u mutex\t对象-这不是问题吗

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

    2:使用相同的pthread\u mutex\u锁锁定多个函数是什么意思?也许只有一个线程可以访问它们中的任何一个?什么时候应该使用不同的pthread\u mutex\t对象

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

    更好的使用: 这很容易受到比赛条件的影响。应该这样写:

    while(<No Tasks available>)
    {
        pthread_cond_wait(manager->getCond(), manager->getLock());
    }
    
    这是一个问题。线程正在消亡,同时仍保持互斥锁。在线程死亡之前,它应该释放互斥锁。最好通过RAII控制互斥体,这样它的使用是异常安全的,您可以通过从函数返回而不是调用pthread_exit()退出线程

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

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