【问题标题】:Getting a segmentation fault after pthread_join in main()在 main() 中的 pthread_join 后出现分段错误
【发布时间】:2012-03-06 06:36:08
【问题描述】:
#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 中加入了线程,也会出现 seg 错误。
  • 在 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

现在第二个线程的弹出值正在打印,但段错误仍然存​​在。

【问题讨论】:

  • std::vector&lt;T&gt; 不是线程安全的。虽然(乍一看)它看起来您只能访问serverInfoVector,同时从checkServerExists 和线程函数printHello 中持有demoMutex,但在for 循环中访问它时不会。这可能不是 SIGSEGV 的实际原因,但它看起来仍然是一个潜在问题。
  • @Christian.K 抱歉,不能很好地理解您的观点。 vector 可能不是线程安全的,但我每次都将它放入锁中。为什么还是有问题?
  • printHello 函数内部,有一个循环遍历serverInfoVector 的元素。循环的条件是i &lt;= serverInfoVector.size()。请注意,它说的是&lt;=,而不是&lt;。会不会超出向量的末端?
  • @Anisha Kaul 当 i 为 4 时,它将最后一次递增。只有这样循环才会终止,而 i 将是 5。更一般地说,在循环终止后,循环条件通常不再有效。
  • @Anisha Kaul 是的,听起来不错。经过所有的调试,现在是当之无愧的休息时间了 :)

标签: c++ pthreads segmentation-fault mutex


【解决方案1】:

分段错误是由于我的 NOT 使用pthread_equal 比较以下代码中的 threadId:

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

感谢@David Schwartz 在此提及:https://stackoverflow.com/a/9564998/462608 和 :doh: 对我来说没有仔细听。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-15
    • 2015-05-02
    • 1970-01-01
    • 2017-04-18
    • 1970-01-01
    • 2017-09-16
    相关资源
    最近更新 更多