2014-01-07 44 views
0

這是代碼片段。我可以設置線程的名稱。但是,檢索線程的名稱時出現錯誤。請幫忙。爲什麼pthread_getname_np()在Linux的線程中失敗?

void *Thread_Function_A(void *thread_arg) 
{ 

    char buf[7]; 

    int rc; 

    pthread_t self; 

    self = pthread_self(); 


    rc = pthread_getname_np(self, buf,7); 

    if (rc != 0) 
    cout<<"Failed getting the name"<<endl; 

} 


int main(int argc, char *argv[]) 
{ 
    int rc; 
    pid_t thread_pid_val = getpid(); 
    thread_1.create_thread((thread_1.get_thread_id()), NULL,Thread_Function_A,&thread_pid_val); 
    thread_2.create_thread((thread_2.get_thread_id()), NULL,Thread_Function_A,&thread_pid_val); 
    rc = pthread_setname_np(*(thread_1.get_thread_id()), "Thread_A"); 
    if(rc != 0) 
    { 
    cout<<"Setting name for thread A failed"<<endl; 
    } 
    rc = pthread_setname_np(*(thread_2.get_thread_id()), "Thread_B"); 
    if(rc != 0) 
    { 
    cout<<"Setting name for thread B failed"<<endl; 
    } 
    pthread_join(*(thread_1.get_thread_id()), NULL); 
    pthread_join(*(thread_2.get_thread_id()), NULL); 

    return 0; 
} 

輸出: -

$./thread_basic.out 
Failed getting the nameFailed getting the name 

The name of thread is The name of thread is 

的字符串錯誤說 - 數值結果超出範圍 誤差= 34

新增現在完整代碼。在這裏,我沒有得到正確的名字。相反,它會檢索程序的名稱。

void *Thread_Function_A(void *thread_arg) 
{ 

    char name[300]; 
    char buf[200]; 

    int rc; 
    char message[100]; 

    FILE *fp; 

    pthread_t self; 

    self = pthread_self(); 


    rc = pthread_getname_np(self, buf,200); 

    if (rc != 0) 
    { 
    cout<<"Failed getting the name"<<endl; 
    cerr<<"Pthread get name error ="<<rc<< " " << strerror(rc) << endl; 
    } 

    sprintf(name,"log_%s.txt",buf); 

    cout<<"The name of thread is "<<buf<<endl; 

    fp = fopen(name,"w+"); 

    for(int i = 1; i<=5; i++) 
    { 
    sprintf(message,"The thread id is %d and value of i is %d",pthread_self(),i); 

    fprintf(fp,"%s\n", message); 
    fflush(fp); 
    /** local variable will not be shared actually**/ 
    /** each thread should execute the loop for 5 **/ 
    /** total prints should be 10 **/ 

    } 

    pthread_exit(NULL); 
} 



int main(int argc, char *argv[]) 
{ 
    int rc; 
    pthread_t threadA, threadB; 
    pid_t thread_pid_val = getpid(); 
    thread_1.create_thread(&threadA, NULL,Thread_Function_A,&thread_pid_val); 
    thread_1.set_thread_id(threadA); 
    rc = pthread_setname_np(threadA, "Thread_A"); 
    if(rc != 0) 
    { 
    cout<<"Setting name for thread A failed"<<endl; 
    } 

    thread_2.create_thread(&threadB, NULL,Thread_Function_A,&thread_pid_val); 
    thread_2.set_thread_id(threadB); 
    rc = pthread_setname_np(threadB, "Thread_B"); 
    if(rc != 0) 
    { 
    cout<<"Setting name for thread B failed"<<endl; 
    } 
    pthread_join(threadA, NULL); 
    pthread_join(threadB, NULL); 

    return 0; 
} 

輸出如下。

]$ ./thread_basic.out 
The name of thread is thread_basic.ou 
The name of thread is Thread_B 
+0

如果您閱讀[手冊頁](http://man7.org/linux/man-pages/man3/pthread_setname_np.3.html),您將看到該函數返回錯誤號(而不是將其設置爲'errno'),你可能想用['strerror'](http://en.cppreference.com/w/c/string/byte/strerror)打印那個(或者可打印的字符串)。 –

+0

超出範圍的數字結果是錯誤。 –

+1

閱讀我之前評論中鏈接到的手冊頁。 –

回答

1

除了競爭條件,它不會讓你的通話失敗,但可能不會返回你想要的,這就是通話失敗的原因。

man 3 pthread_getname_np

的pthread_getname_np()函數可以被用於檢索線程的名稱。線程參數指定要檢索其名稱的線程。緩衝區名稱用於返回線程名稱; len指定名稱中可用的字節數。 名稱指定的緩衝區長度至少應爲16個字符。輸出緩衝區中返回的線程名將以null結尾。

char buf[7]; 

是要失敗的。

+0

我能夠自己糾正它。但是,設置名稱存在問題。它沒有設置名稱。我將再次寫出這個場景。 –

+0

它沒有設置名稱,因爲在你設置主名稱之前,你的線程已經完成並完成了。這是幾個人提到的競爭條件。 – Duck

+0

我該如何解決它? –

1

您正在使用的C和C++的功能,你應該避免混合,並用代碼,我們無法驗證部分,e.g你的方法get_thread_id。但是你的代碼的問題是顯而易見的,你試圖很早就獲得線程的名字:你的main沒有絲毫的機會在線程已經終止之前放置這些名字。

此外,你的線程函數是不正確的,任何具有最低級別警告的編譯器都應該告訴你。具有非void返回類型的函數需要return語句。在C中,這隻會導致未定義的行爲,如果你使用函數的返回值,你不知道,因爲它是調用你的函數的線程庫。

+0

解決這種競爭狀況的方法是什麼? –

+0

@SHREYASJOSHI,對於任何這種類型的互斥和條件變量的組合是你的朋友。這就是* POSIX中*的方式來保證無處不在的coordiante線程。 –

+0

我在main()中設置名稱,並在線程例程中讀取它。如何同步這些事件? –