2012-03-06 11 views
1
#include <pthread.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <vector> 
#include <string> 
#include <iostream> 

pthread_mutex_t demoMutex   = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t conditionVariable = PTHREAD_COND_INITIALIZER; 
unsigned int condition   = 0; 

struct serverInfo 
{ 
    unsigned int     serverId; 
    pthread_t      threadId; 
    std :: vector <std :: string> queue; 
}; 
std :: vector <serverInfo> serverInfoVector; 

void print_thread_id(pthread_t id) 
{ 
    size_t i; 
    for (i = sizeof(i); i; --i) 
     printf("%02x", *(((unsigned char*) &id) + i - 1)); 
} 

void * printHello (void* threadId) 
{ 
    pthread_t *my_tid = (pthread_t *)threadId; 

    pthread_mutex_lock (&demoMutex); 

    while (condition == 0) 
     pthread_cond_wait (&conditionVariable, &demoMutex); 

    unsigned int i = 0; 
    char   found = false; 

    if (serverInfoVector.size() > 0) 
    { 
     while ((i < serverInfoVector.size()) && (found == false)) 
     { 
      if (*my_tid == serverInfoVector [i].threadId) 
      { 
       found = true; 
       break; 
      } 
      else 
       i++; 
     } 
    } 

    while (!serverInfoVector [i].queue.empty()) 
    { 
     std :: cout << "\nThread: " << pthread_self() << ", poped from queue: " << serverInfoVector [i].queue.front(); 
     serverInfoVector [i].queue.pop_back(); 
    } 

    pthread_mutex_unlock (&demoMutex); 
    pthread_exit (NULL); 
} 

void checkServerExists (unsigned int serverNumber, std :: string message) 
{ 
    unsigned int i  = 0; 
    char   found = false; 

    pthread_mutex_lock (&demoMutex); 

    if (serverInfoVector.size() > 0) 
    { 
     while ((i < serverInfoVector.size()) && (found == false)) 
     { 
      if (serverNumber == serverInfoVector [i].serverId) 
      { 
       found = true; 
       break; 
      } 
      else 
       i++; 
     } 
    } 

    if (found == false) 
    { 
     // This server doesn't exist, so create a thread for it, create a queue for it, push the message in the corresponding queue. 
     // Push the server number in the serverNumberArray. 

     // Create a thread for it. 
     pthread_t newThread; 
     int returnValue; 
     if ((returnValue = pthread_create (&newThread, 
            NULL, 
            printHello, 
            (void*) &newThread)) != 0) 
     { 
      printf ("\nerror: pthread_create failed with error number %d", returnValue); 
     } 
     printf ("\nIn checkServerExists()`: thread id %ld\n", newThread); 
     print_thread_id (newThread); 

     // Push the message in its queue. 
     serverInfo obj; 
     obj.serverId = serverNumber; 
     obj.threadId = newThread; 
     obj.queue.push_back (message); 
     serverInfoVector.push_back (obj); 

     condition++; 
     pthread_cond_signal (&conditionVariable); 
     pthread_mutex_unlock (&demoMutex); 
    } 
    else 
    { 
     // This server exists, so lookup its thread and queue, push the message in the corresponding queue. 
     printf ("\nIn else()`: thread id %ld\n", serverInfoVector [i].threadId); 
     serverInfoVector [i].queue.push_back (message); 

     condition++; 
     pthread_cond_signal (&conditionVariable); 
     pthread_mutex_unlock (&demoMutex); 
    } 
} 

int main() 
{ 
    checkServerExists (1, "anisha"); 
    checkServerExists (2, "kaul"); 
    checkServerExists (1, "sanjeev"); 
    checkServerExists (2, "sharma"); 

    for (unsigned int i = 0; i < serverInfoVector.size(); i++) 
     pthread_join (serverInfoVector [i].threadId, NULL); 

    return 0; 
} 

出力:)(メインでpthread_joinを後にセグメンテーションフォールトを取得

In checkServerExists()`: thread id 139875161245456 
00007f37394c8710 
In checkServerExists()`: thread id 139875152852752 
00007f3738cc7710 
In else()`: thread id 139875161245456 

In else()`: thread id 139875152852752 

Segmentation fault 
  • 問題は、私は私がメインのスレッドに参加している場合でも取得していますワンセグ障害です。
  • OpenSuseでpthread_tはunsigned longとtypedefedされていますので、印刷しようとしました。また、私はここに示すように機能print_thread_idを呼び出そうとしています:https://stackoverflow.com/a/1759894/462608

リトル改善:

In checkServerExists()`: thread id 139975945303824 
00007f4eb07f3710 
In checkServerExists()`: thread id 139975936911120 
00007f4eafff2710 
In else()`: thread id 139975945303824 

In else()`: thread id 139975936911120 

Thread: 139975936911120, poped from queue: 1kaul1�&��N�&��Na7�Npq`�q`�q`'��N�s`�s`�s`!�q`!�q`�s`1sharma 
                             Segmentation fault 

を今第二のスレッドからpoped値が印刷されつつあるが、それでもワンセグ障害が持続します。セグメンテーションフォールトが次のコードでthreadIdsの比較のためにpthread_equalを使用して、私のませによるものであった

+0

'std :: vector 'はスレッドセーフではありません。 (一見すると) 'checkServerExists'とスレッド関数' printHello'の中から 'demoMutex'を保持している間だけ' serverInfoVector'にアクセスしますが、あなたはforループでアクセスしていません。これはSIGSEGVの実際の理由ではないかもしれませんが、潜在的な問題のように見えます。 –

+0

@ Christian.K申し訳ありませんが、あなたのポイントをよく理解できませんでした。ベクトルはスレッドセーフではないかもしれませんが、毎回ロックに入れています。なぜそれはまだ問題ですか? –

+0

はい、しかし、あなたが 'main()'で_read_していないときは、実際には、スレッド内から 'serverInfoVector'を実際に変更しないかのように見えるので、' for'ループを実行する際には、少なくとも 'threadID'メンバーのサイズと内容が固定されている必要があります。私が言ったように、それはSIGSEGVの理由ではないかもしれませんが、とにかく壊れやすいように見えます。 YMMV。 –

答えて

2

:それをここに言及するため@デビッド・シュワルツ

if (serverInfoVector.size() > 0) 
    { 
     while ((i < serverInfoVector.size()) && (found == false)) 
     { 
      if (*my_tid == serverInfoVector [i].threadId) 
      { 
       found = true; 
       break; 
      } 
      else 
       i++; 
     } 
    } 

ありがとう:https://stackoverflow.com/a/9564998/462608 と:DOH:慎重に聞いていないために私に。

関連する問題