2016-09-21 77 views
1

以下面的代码为例。在pthread_con_wait中,activeMutex被锁定。然后是行“pthread_mutex_unlock(& activeMutex)”必要?因为主要功能即将结束。或者,如果我删除该行,主完成后互斥锁将自动解锁。是否有必要在主结束时解锁互斥锁?

#include <pthread.h> 
#include <iostream> 

using namespace std; 

int activeThreads = 0; 

pthread_mutex_t coutMutex; 
pthread_mutex_t activeMutex; 
pthread_cond_t allDoneCondition; 

void* Thread(void* v) 
{ 
    unsigned long myId = (unsigned long)v; 

    pthread_mutex_lock(&coutMutex); 
    cout << "Hello from thread " << myId << endl; 
    pthread_mutex_unlock(&coutMutex); 
    pthread_mutex_lock(&activeMutex); 
    activeThreads--; 
    if (activeThreads == 0) 
    { 
    pthread_cond_signal(&allDoneCondition); 
    } 
    pthread_mutex_unlock(&activeMutex); 
} 

int main(int argc, char** argv) 
{ 
    int totalThreads = 8; 
    pthread_mutex_init(&coutMutex, 0); 
    pthread_mutex_init(&activeMutex, 0); 
    pthread_cond_init(&allDoneCondition, 0); 

    pthread_mutex_lock(&activeMutex); 
    activeThreads = totalThreads; 
    for (int i = 0; i < totalThreads; ++i) 
    { 
     pthread_t t; 
     pthread_create(&t, 0, Thread, (void*)i); 
    } 
    cout << "Hello from main before exit" << endl; 
    pthread_cond_wait(&allDoneCondition, &activeMutex); 
    pthread_mutex_unlock(&activeMutex); 
} 
+0

使用C++的正确,使之成为非问题。清理干净的东西。当你用这个代码的模糊的记忆,包起来一起10年晚一点到一些其他项目库 – GManNickG

回答

4

main所有的节目资源的结束将通过操作系统进行清理。不释放这个互斥量可能没有任何负面影响。真正的问题是,为什么你不释放它?没有释放它并没有获得任何好处,并且你拥有解锁每个锁的好习惯(即良好的资源管理)。

这是针对您的特定代码的,如果它是忘记释放互斥锁的打开的线程,则需要更加小心,请参阅here

+2

也很烂,然后,很多经过调试,实现了图书馆的锁,因为你年轻,愚蠢和懒惰十年早。 – user4581301

1

有两个方面对这个问题:

  1. 你应该行使当你用它做解锁互斥的良好健康习惯吗?
  2. 你应该有明确地浪费你的(希望)宝贵的时间解锁的东西呢?

这是C++,所以你有RAII的选项,并做类似C++ 11 <thread>头做了什么事:

#include <iostream> 
#include <utility> 
#include <pthread.h> 

struct mutex_lock_t { 
    pthread_mutex_t* mutex_ { nullptr }; 
public: 
    mutex_lock_t() = default; 
    mutex_lock_t(pthread_mutex_t& mutex) : mutex_(&mutex) { pthread_mutex_lock(mutex_); } 
    void unlock() 
    { 
     if (mutex_) { pthread_mutex_unlock(std::exchange(mutex_, nullptr)); } 
    } 
    ~mutex_lock_t() noexcept { unlock(); } 

    mutex_lock_t(const mutex_lock_t&) = delete; 
    mutex_lock_t(mutex_lock_t&&) = delete; 
    mutex_lock_t operator=(const mutex_lock_t&) = delete; 
    mutex_lock_t operator=(mutex_lock_t&&) = delete; 
}; 

int main() 
{ 
    pthread_mutex_t mutex {}; 
    pthread_mutex_init(&mutex, nullptr); 
    mutex_lock_t lock(mutex); 
    std::cout << "end of main\n"; 
} // auto unlock at end of scope 

这里的好处是,“我必须”是不再是一个问题,你只是。

如果你不这样做,那么一个典型的互斥体在进程内存中举行,会简单地停止与任何进程终止时,可能有机会获得它一起存在。

但是,如果在未来,你的程序的变化和使用互斥在共享内存与其他进程,那么它是更好地依靠RAII清理,而不是过程的清理。