2017-06-20 78 views
-1

我在繼承類中使用了互斥鎖,但似乎無法像我期望的那樣使用線程。請在下面的代碼看看:互斥鎖不能正常工作

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

// mutex::lock/unlock 
#include <iostream>  // std::cout 
#include <thread>   // std::thread 
#include <chrono>   // std::thread 
#include <mutex>   // std::mutex 

typedef unsigned int UINT32t; 
typedef int INT32t; 

using namespace std; 



class Abstract { 

protected: 
    std::mutex mtx; 
}; 


class Derived: public Abstract 
{ 
public: 
    void* write(void* result) 
    { 
     UINT32t error[1]; 
     UINT32t data = 34; 
     INT32t length = 0; 
     static INT32t counter = 0; 

     cout << "\t before Locking ..." << " in thread" << endl; 

     mtx.lock(); 
     //critical section 
     cout << "\t After Create " << ++ counter << " device in thread" << endl; 

     std::this_thread::sleep_for(1s); 

     mtx.unlock(); 
     cout << "\t deallocated " << counter << " device in thread" << endl; 
     pthread_exit(result); 
    } 
}; 

void* threadTest1(void* result) 
{ 
    Derived dev; 

    dev.write(nullptr); 
} 


int main() 
{ 
    unsigned char byData[1024] = {0}; 
    ssize_t len; 
    void *status = 0, *status2 = 0; 
    int result = 0, result2 = 0; 

    pthread_t pth, pth2; 
    pthread_create(&pth, NULL, threadTest1, &result); 
    pthread_create(&pth2, NULL, threadTest1, &result2); 


    //wait for all kids to complete 
    pthread_join(pth, &status); 
    pthread_join(pth2, &status2); 

    if (status != 0) { 
      printf("result : %d\n",result); 
     } else { 
      printf("thread failed\n"); 
     } 


    if (status2 != 0) { 
      printf("result2 : %d\n",result2); 
     } else { 
      printf("thread2 failed\n"); 
     } 


    return -1; 
} 

所以結果是:

*四或五個參數的預期。

before Locking ... in thread 
    After Create 1 device in thread 
    before Locking ... in thread 
    After Create 2 device in thread 
    deallocated 2 device in thread 
    deallocated 2 device in thread 
     thread failed 
     thread2 failed 

*

所以在這裏我們可以看到,第二個線程來臨界區被釋放互斥之前。 字符串「在線程中創建2設備之後」對此進行了說明。 如果說在釋放互斥體之前的臨界區域,這意味着互斥體的工作是錯誤的。

如果您有任何想法,請分享。

感謝

+0

不要手動鎖定和解鎖互斥鎖。這樣做會使您有可能漏鎖。改爲使用'std :: lock_guard'或'std :: unique_lock'。 –

回答

4

編輯:tkausl的答案是正確的 - 但是,即使你切換到使用全球互斥,輸出可能不是因爲在我的答案細節的,所以我離開這裏改變它。換句話說,輸出可能不是你所期望的有兩個原因,你需要解決這兩個問題。


請特別注意以下兩行:

mtx.unlock(); 
cout << "\t deallocated " << counter << " device in thread" << endl; 

你似乎是的印象是,這兩條線將運行在一個又一個的權利,但也不能保證這不會發生在搶先的多線程環境中。可能發生的情況是mtx.unlock()之後可能會有一個上下文切換到另一個線程。

換句話說,第二螺紋等待互斥體解鎖,但第二個線程搶佔它之前第一線程不打印的「解除分配」的消息。

獲得預期輸出的最簡單方法是交換這兩行的順序。

6

互斥體本身(可能)工作正常(雖然我建議您使用std::lock_guard),但是兩個線程都創建了自己的Derived對象,因此它們不使用相同的互斥體。

1

在調用pthread_create之前,您應將您的互斥量聲明爲全局變量並啓動它。您使用pthread_create創建了兩個線程,並且它們都創建了自己的互斥鎖,因此它們之間完全沒有同步。