【问题标题】:How to sort an array of n elements using n - 1 threads如何使用 n - 1 个线程对包含 n 个元素的数组进行排序
【发布时间】:2014-03-11 13:43:14
【问题描述】:

我必须使用n - 1 线程对n 元素数组进行排序。对于每个线程,我测试一个等于 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);
}

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

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

【问题讨论】:

  • 你的排序有多少个元素?您最多实现了一个 O(nnn) 算法。如果pthread_mutex_unlock() 不是恒定时间操作,情况可能会更糟。如果pthread_mutex_unlock() 不是真正的公平,它可能永远不会结束。我只是在谈论算法,我没有仔细查看您程序中的错误。我认为你应该重新考虑你的算法,并设计一个不同的解决方案。
  • 我正在对 n 个元素进行排序。我无法更改算法,我必须使用精确的 n - 1 线程对 n 元素进行排序。

标签: c multithreading sorting unix pthreads


【解决方案1】:

这段代码:

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

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

解决这个问题的一个hacky方法是传入一个指针值,该指针值对应于您希望线程接收的整数值。

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;

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-10
    • 2019-04-10
    • 2010-09-15
    • 1970-01-01
    • 2020-04-22
    • 2021-06-03
    • 2021-03-12
    • 2020-10-27
    相关资源
    最近更新 更多