如何使用n - 1个线程对n个元素的数组进行排序

时间:2014-03-11 13:43:14

标签: c multithreading sorting unix pthreads

我必须使用n个线程对n - 1个元素进行排序。对于每个线程,我测试一个等于0的布尔标志是位置ii+1中的元素必须交换,否则它将被设置为1.每个线程体都是一个结束的函数只有当所有元素都在正确的位置时,所有标志都等于1。

以下是我创建线程并加入它们的主要功能(一些变量是全局的):

int i;
pthread_t threads[n - 1];

// init the array with random values
array = init_array(n);
len = n;

// flags to check if the array is sorted
is_array_sorted = 0;
is_sorted = calloc(n - 1, sizeof(int));

// prints the initial array
print_array(array, n);

// init the mutex
pthread_mutex_init(&lock, NULL);

// create n - 1 threads
for (i = 0; i < n - 1; i++)
{
    if (pthread_create(&threads[i], NULL, swap, (void*)&i) != 0)
        exit(EXIT_FAILURE);
}

// waits until all threads end
for (i = 0; i < n - 1; i++)
{
    if (pthread_join(threads[i], NULL) != 0)
        exit(EXIT_FAILURE);
}

// destroy the mutex
pthread_mutex_destroy(&lock);

// prints the sorted array
print_array(array, n);

// free memory
free(array);
free(is_sorted);

这是线程体功能:

static void* swap(void* args)
{
    // Indiex of the element to check (j and j+1)
    int j = *((int*)args);

    // while the array is not sorted
    while (1)
    {
        int i;

        // start mutual exclusion
        pthread_mutex_lock(&lock);

        // check if we have to swap elements
        if (array[j] > array[j+1])
        {
            // swap elements
            int temp = array[j];
            array[j] = array[j + 1];
            array[j + 1] = temp;
        }

        // now the elements in position j and j+1 are in the right order
        is_sorted[j] = 1;
        is_array_sorted = 1;

        // check if all elements are sorted
        for (i = 0; i < len - 1; i++)
        {
            if (is_sorted[i] == 0)
            {
                is_array_sorted = 0;
                break;
            }
        }

        if (is_array_sorted)
        {
            // the array is sorted, terminate the thread
            pthread_mutex_unlock(&lock);
            break;
        }

        pthread_mutex_unlock(&lock);
    }

    pthread_exit(NULL);
}

问题是这个程序永远不会结束。 为什么?我该如何解决这个问题?

请注意,这是一项多线程练习,不需要性能或最佳解决方案。

1 个答案:

答案 0 :(得分:0)

此代码:

for (i = 0; i < n - 1; i++)
{
    if (pthread_create(&threads[i], NULL, swap, (void*)&i) != 0)

可能没有做你认为它应该做的事情。只有一个变量i,您将地址传递给i到所有线程。每次启动另一个线程时,i都会递增。无法保证每个线程在访问传入的地址时都会看到唯一值。

处理此问题的一种愚蠢的方法是传入一个指针值,该指针值对应于您希望线程接收的整数值。

char *x = 0;
for (i = 0; i < n - 1; i++)
{
    if (pthread_create(&threads[i], NULL, swap, x++) != 0)

线程函数可以像这样解码它:

    int j = (char*)args - (char *)0;

正如我在评论中已经说过的那样,您的排序方法非常不受欢迎,应该进行重新设计。我认为,对这个解决方案给予高度评价的老师并不会高度评价学生的能力。