Получение ошибки сегментации после pthread_join в main () - PullRequest
1 голос
/ 06 марта 2012
#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;
}

Выход:

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

In else ()`: thread id 139875152852752

Segmentation fault
  • Проблема в сбое сегмента, которое я получаю, даже когда присоединяюсь к потокам в main.
  • В OpenSuse pthread_t определено как unsigned long, поэтому я попытался напечатать его. Также я попытался вызвать функцию 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 из второго потока, но ошибка seg сохраняется.

1 Ответ

2 голосов
/ 06 марта 2012

Ошибка сегментации произошла из-за того, что мой НЕ использовал pthread_equal для сравнения ThreadIds в следующем коде:

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: мне, что я не слушаю внимательно.

...