C-使用多线程编程从命令行计算统计值

时间:2018-10-25 23:37:45

标签: c multithreading

我是C练习程序的初学者,可以为从命令行读取的数字列表计算各种统计值。但是,当尝试在Linux上编译我的代码时,我遇到了一些不确定的错误,并且不确定是否可以从比我自己更熟悉C语言的人那里得到一些帮助。我已经在下面包含了我的代码和错误。

我的代码:

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

int *values;
int size;
double avg=0.0;
int minValue=0;
int maxValue=0;
void *runAvg(void *param);
void *runMin(void *param);
void *runMax(void *param);

int main (int argc, char *argv[]){
    if(argc != 2){
        fprintf(stderr, "usage: %s <integer value>\n", argv[0]);
    }
    int i;
    for(i=1; i < argc; i++){
        values=&(atoi(argv[i]));
        size++;
    }

    pthread_t avgPt[size];
    pthread_t minPt[size];
    pthread_t maxPt[size];
    pthread_attr_t attr;

    //create threads
        pthread_create(&avgPt, &attr, runAvg, values);
        pthread_create(&minPt, &attr, runMin, values);
        pthread_create(&maxPt, &attr, runMax, values);
    //wait for threads to exit
        pthread_join(avgPt, NULL);
        pthread_join(minPt, NULL);
        pthread_join(maxPt, NULL);
    //print results of threads
        printf("\n Average: %f \n",avg);
        printf("\n Minimum: %d \n",minValue);
        printf("\n Maximum: %d \n",maxValue);
}

void *runAvg(void *param){

    int sum=0;
    int i=0;
    int *values;
    values=(int*)param;
    for(i=0;i<size; i++) sum += values[i];
    avg = sum / (double)size;

    pthread_exit(0);
}

void *runMin(void *param){

    int i=0;
    int *values;
    values=(int*)param;
    minValue = values[0];

    for(i=0;i<size;i++){
        if(values[i]<minValue){
            minValue=values[i];
        }
    }
    pthread_exit(0);
}

void *runMax(void *param){

    int i=0;
    int *values;
    values=(int*)param;
    maxValue=values[0];

    for(i=0;i<size;i++){
        if(values[i] > maxValue){
            maxValue = values[i];
        }
    }
    pthread_exit(0);
}

我的编译错误:

423assign.c:20: error: lvalue required as unary ‘&’ operand
423assign.c:30: warning: passing argument 1 of ‘pthread_create’ from
incompatible pointer type
/usr/include/pthread.h:227: note: expected ‘pthread_t * __restrict__’
but argument is of type ‘pthread_t (*)[(unsigned int)(size)]’
423assign.c:31: warning: passing argument 1 of ‘pthread_create’ from
incompatible pointer type
/usr/include/pthread.h:227: note: expected ‘pthread_t * __restrict__’
but argument is of type ‘pthread_t (*)[(unsigned int)(size)]’
423assign.c:32: warning: passing argument 1 of ‘pthread_create’ from
incompatible pointer type
/usr/include/pthread.h:227: note: expected ‘pthread_t * __restrict__’
but argument is of type ‘pthread_t (*)[(unsigned int)(size)]’
423assign.c:34: warning: passing argument 1 of ‘pthread_join’ makes
integer from pointer without a cast
/usr/include/pthread.h:244: note: expected ‘pthread_t’ but argument is
of type ‘pthread_t *’
423assign.c:35: warning: passing argument 1 of ‘pthread_join’ makes
integer from pointer without a cast
/usr/include/pthread.h:244: note: expected ‘pthread_t’ but argument is
of type ‘pthread_t *’
423assign.c:36: warning: passing argument 1 of ‘pthread_join’ makes
integer from pointer without a cast
/usr/include/pthread.h:244: note: expected ‘pthread_t’ but argument is
of type ‘pthread_t *’

1 个答案:

答案 0 :(得分:1)

您的线程功能还可以。

一个问题是分配int数组以包含atoi中的值。

此外,您的pthread_t变量应该不是是数组。并且您的attr值永远不会被初始化和使用。


这是一个经过清理的版本,其中注释并修复了错误[请原谅免费的样式清理]:

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

int *values;
int size;
double avg = 0.0;
int minValue = 0;
int maxValue = 0;
void *runAvg(void *param);
void *runMin(void *param);
void *runMax(void *param);

int
main(int argc, char **argv)
{

// NOTE/BUG: this should be "< 2" and not "!= 2"
    if (argc < 2) {
        fprintf(stderr, "usage: %s <integer value>\n", argv[0]);
        exit(1);
    }
    int i;

    --argc;
    ++argv;

// NOTE/BUG: we must allocate an int array of sufficient size
    values = calloc(argc,sizeof(int));

    for (i = 0;  i < argc;  i++) {
        values[i] = atoi(argv[i]);
        size++;
    }

// NOTE/BUG: these should _not_ be arrays
    pthread_t avgPt;
    pthread_t minPt;
    pthread_t maxPt;

// NOTE/BUG: this is unitialized and it's not set to anything, so the
// pthread_create 2nd argument can [and should be] NULL
#if 0
    pthread_attr_t attr;
#endif

    // create threads
#if 0
    pthread_create(&avgPt, &attr, runAvg, values);
    pthread_create(&minPt, &attr, runMin, values);
    pthread_create(&maxPt, &attr, runMax, values);
#else
    pthread_create(&avgPt, NULL, runAvg, values);
    pthread_create(&minPt, NULL, runMin, values);
    pthread_create(&maxPt, NULL, runMax, values);
#endif

    // wait for threads to exit
    pthread_join(avgPt, NULL);
    pthread_join(minPt, NULL);
    pthread_join(maxPt, NULL);

    // print results of threads
    printf("\n Average: %f \n", avg);
    printf("\n Minimum: %d \n", minValue);
    printf("\n Maximum: %d \n", maxValue);
}

void *
runAvg(void *param)
{

    int sum = 0;
    int i = 0;
    int *values;

    values = param;
    for (i = 0; i < size; i++)
        sum += values[i];
    avg = sum / (double) size;

    return (void *) 0;
}

void *
runMin(void *param)
{

    int i = 0;
    int *values;

    values = param;
    minValue = values[0];

    for (i = 0; i < size; i++) {
        if (values[i] < minValue)
            minValue = values[i];
    }

    return (void *) 0;
}

void *
runMax(void *param)
{

    int i = 0;
    int *values;

    values = param;
    maxValue = values[0];

    for (i = 0; i < size; i++) {
        if (values[i] > maxValue)
            maxValue = values[i];
    }

    return (void *) 0;
}