【问题标题】:Find max in array using threads?使用线程在数组中查找最大值?
【发布时间】:2015-04-19 14:20:32
【问题描述】:

你将如何在 c 中使用二进制归约和使用二进制信号量实现的屏障来做到这一点?这是我到目前为止的代码。它没有障碍,我对如何制作一个感到困惑。我需要互斥锁吗?

# include <stdio.h>
# include <pthread.h>
# define arrSize 10

struct StructMax
{
    int iMax;
};

int arr[arrSize];

void *thread_search_max(void *);

int main()
{
    pthread_t tid;
    struct StructMax *st_main,*st_th;
    int FinalMax;

    st_main=(struct StructMax*)malloc(sizeof(struct StructMax));

    int iCount;
    for(iCount=0;iCount<arrSize;iCount++)
    {
        printf("Enter Value of arr[%d] :",iCount);
        scanf("%d",&arr[iCount]);
    }        
    pthread_create(&tid,NULL,thread_search_max,NULL);

    st_main->iMax=arr[0];

    for(iCount=1;iCount<arrSize/2;iCount++)
    {
        if(arr[iCount] > st_main->iMax)
        {
            st_main->iMax=arr[iCount];
        }
    }    

    pthread_join(tid,(void**)&st_th);    

    if(st_main->iMax >= st_th->iMax)
    {
        FinalMax=st_main->iMax;
    }    
    else
    {
        FinalMax=st_th->iMax;
    }


    printf("Final Max : %d \n",FinalMax);
    return 0;
}


void *thread_search_max(void *para)
{
    struct StructMax *st;
    st=(struct StructMax*)malloc(sizeof(struct StructMax));

    int iCount;
    st->iMax=arr[arrSize/2];


    for(iCount=arrSize/2 + 1;iCount<arrSize;iCount++)
    {
        if(arr[iCount] > st->iMax)
        {
            st->iMax=arr[iCount];
        }
    }    

    pthread_exit((void*)st);        
}

【问题讨论】:

  • Don't cast the return value of malloc() in C。将您的分配写为:st_main = malloc(sizeof *st_main);。更短,没有毫无意义的强制转换,也更安全。
  • 和几乎所有其他人一样,您投射malloc()which is not needed 但忽略它的返回值,这是不好的做法。另外,使用互斥体,不要使用全局变量,通过pthread_create 的最后一个参数将数组传递给线程函数。请记住,每个malloc() 都应该在某处与free() 匹配。
  • 信号量?障碍?我会避免他们在数组中搜索最大值,它们会损害性能足以将您推回直接的非并行执行。如果您这样做是为了提高性能,我会考虑使用 atomics (通过非常仔细的实现)甚至(如果您的架构允许您使用此 trick)使用 易变.

标签: c multithreading pthreads semaphore barrier


【解决方案1】:

您没有包含 stdlib.h:这是主要问题,但您还应该考虑一些其他小的修复,以使您的代码更加健壮。

不包含stdlib.h的问题是编译器假定malloc()返回一个int,所以你可以看到这会导致问题。

如果你启用编译器警告,你可以防止这种事情发生,我有时会忘记一些标题,但我并没有走得太远,因为编译器提醒了我。

假设您使用gcc 那么

gcc -Wall -Werror -o output $sourceFiles -pthread

在这种情况下会阻止编译。

这是您的程序的改进版本,包含 stdlib.h 标头

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define arrSize 10

struct StructMax
{
    int iMax;
};

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void *thread_search_max(void *);

int main()
{
    pthread_t         tid;
    struct StructMax *st_main;
    struct StructMax *st_th;
    int               FinalMax;
    int               arr[arrSize];

    st_main = malloc(sizeof(struct StructMax));
    if (st_main == NULL)
        return -1;
    int iCount;
    for (iCount = 0 ; iCount < arrSize ; iCount++)
    {
        printf("Enter Value of arr[%d] :",iCount);
        scanf("%d",&arr[iCount]);
    }
    pthread_create(&tid, NULL, thread_search_max, arr);

    /* lock the mutex, in this secction we access 'arr' */
    pthread_mutex_lock(&mutex);
    st_main->iMax = arr[0];
    pthread_mutex_unlock(&mutex);

    for (iCount = 1 ; iCount < arrSize / 2 ; iCount++)
    {
        /* lock the mutex, in this secction we access 'arr' */
        pthread_mutex_lock(&mutex);
        if (arr[iCount] > st_main->iMax)
        {
            st_main->iMax = arr[iCount];
        }
        pthread_mutex_unlock(&mutex);
    }
    pthread_join(tid, (void **)&st_th);

    if (st_main->iMax >= st_th->iMax)
    {
        FinalMax = st_main->iMax;
    }
    else
    {
        FinalMax = st_th->iMax;
    }
    printf("Final Max : %d \n", FinalMax);
    free(st_th);
    free(st_main);
    return 0;
}

void *thread_search_max(void *para)
{
    struct StructMax *st;
    int               iCount;
    int              *arr;

    arr = para;
    if (arr == NULL)
        return NULL;
    st = malloc(sizeof(struct StructMax));
    if (st == NULL)
        return NULL;
    /* lock the mutex, in this secction we access 'arr' */
    pthread_mutex_lock(&mutex);
    st->iMax = arr[arrSize/2];
    pthread_mutex_unlock(&mutex);
    for (iCount = arrSize /  2 + 1 ; iCount < arrSize ; iCount++)
    {
        /* lock the mutex, in this secction we access 'arr' */
        pthread_mutex_lock(&mutex);
        if (arr[iCount] > st->iMax)
        {
            st->iMax = arr[iCount];
        }
        pthread_mutex_unlock(&mutex);
    }
    pthread_exit((void *)st);
}

查看mutex 的用法,它可以防止两个线程同时访问该值。以及如何不需要全局变量,此外在多线程时它们是一个非常糟糕的主意。

【讨论】:

  • 如果你必须从一堆线程开始,每个线程都包含两个数字,然后他们必须从那里构建解决方案,你会怎么做?让我们假设数组大小是 2 的幂,为了我和你的理智。
【解决方案2】:

除了上述优化之外,应该使用指定可连接的属性创建 pthread(以保证 pthread_join() 将阻塞,直到指定的线程完成)。您可以通过声明 pthread_attr_t 类型的“attr”来做到这一点。 示例代码如下所示。

pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_t tid;

pthread_create(&tid, &attr, function, args);
//....
pthread_attr_destroy(&attr);

pthread_join(&tid, (void **)status);

在 pthread_join() 之前调用 pthread_attr_destroy(),因为一旦使用适当的参数调用 pthread_create(),就不再需要 attr。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-03
    • 2020-08-20
    • 2016-08-12
    • 2010-09-18
    • 2019-09-18
    相关资源
    最近更新 更多