在 pthread_create 中使用时参数会损坏

Arguments become corrupt when used in pthread_create

我正在尝试学习多线程,我认为并行化算法是一个很好的练习。 Quicksort and Merge sort 特别是。

我的问题是参数从调用 pthread_create 到进入与调用关联的函数的过程中损坏。

我的快速排序函数如下所示

static void* quick_sort( void* threadData )
{
    struct ThreadData* data = (struct ThreadData*)threadData;

    unsigned pivot_index;

    pthread_mutex_lock( &lock );
        printf( "\nThread %d : Entering quick_sort with low = %d, high = %d ", data->threadID, data->low, data->high );
    pthread_mutex_unlock( &lock );

    // No need to sort a vector of zero or one element 
    if ( data->low >= data->high )
            return NULL;


    // Select the pivot value 
    pivot_index = ( data->low + data->high ) / 2;

    // Partition the vector 
    pivot_index = partition( data->collection, data->low, data->high, pivot_index );


    /*              Set thread data                  */
    //-------------------------------------------------
    struct ThreadData left, right;
    left.collection = data->collection;
    left.low    = data->low;
    left.high   = pivot_index - 1;
    left.threadID   = data->threadID;

    right.collection = data->collection;
    right.low    = pivot_index + 1;
    right.high   = data->high;
    right.threadID   = data->threadID;
    //------------------------------------------------


    /* sort the two sub arrays */
    if ( data->low < pivot_index )
    {
        pthread_mutex_lock( &lock );            // Lock mutex
        if( numRunningThreads < NUM_THREADS )   // Check for an available thread
        {
            // Find available thread index
            int j;
            for( j = 0; j < NUM_THREADS; j++ )
            {
                if( !runningThreads[j] )
                {
                    left.threadID = j;          // threadPool[j] is available
                    runningThreads[j] = true;   // Set thread as running
                    break;
                }
            }
            /* Use mutex lock when incrementing numRunningThreads
               since it is a global variable and shared by all threads */
            numRunningThreads++;

            printf( "\n     Dispatching thread %d -- ", j );
            printf( "low = %d, high = %d, pivot_index = %d, threadID = %d  ---", left.low, left.high, pivot_index, left.threadID );
            printf( "  %d threads running", numRunningThreads );

            pthread_mutex_unlock( &lock );

            // Create new thread
            pthread_create( &threadPool[left.threadID], NULL, &quick_sort, (void*)&left );
        }
        else
        {
            // There are NO available threads
            pthread_mutex_unlock( &lock );
            quick_sort( (void*)&left ); // Use existing thread
        }
    }

    if ( pivot_index < data->high )
        quick_sort( (void*)&right );

    return NULL;
}

编辑
´pthread_create´的用法是

  pthread_create( &threadPool[left.threadID], NULL, &quick_sort, (void*)&left );


该函数最初是从 main:

调用的
// Use first thread in threadPool
runningThreads[0] = true;
numRunningThreads++;
pthread_create( &threadPool[0], NULL, &quick_sort, (void*)&threadData );

// Join threads
for( i = 0; i < NUM_THREADS; i++ )
{
    if( runningThreads[i] )
    {
        pthread_join( threadPool[i], NULL );

        pthread_mutex_lock( &lock );
            printf( "\nJoining thread %d", i );
            runningThreads[i] = false;
            numRunningThreads--;
        pthread_mutex_unlock( &lock );
    }
}

根据输出,输入函数时数据已损坏

Thread 3 : Entering quick_sort with low = -259450448, high = 32567

对我做错了什么有什么想法吗?

在线程中定义并初始化了一个自动变量left

struct ThreadData left, right;

然后在特定条件下该变量被传递给新创建的线程。这不是在任何类型的锁定机制下完成的:

pthread_create( &threadPool[left.threadID], NULL, &quick_sort, (void*)&left );

创建该线程并向其传递left后,当前线程可以立即退出,同时创建的线程仍在运行并使用变量left:

if ( pivot_index < data->high )
    quick_sort( (void*)&right );

return NULL;

然后变量 left 停止存在,但仍在使用,导致未定义的行为。

解决方案是使用分配的变量,即使用malloc,将这些变量传递给创建的线程,并在不再使用时释放它们。