Передавая параметр в поток, но получаю, я получаю совершенно другие результаты, чем ожидалось

#c #multithreading #pthreads #parameter-passing

#c #многопоточность #pthreads #передача параметров

Вопрос:

Я совершенно новичок в C, так что извините меня за недостаток знаний. Я пытаюсь создать 4 потока, каждый из которых будет генерировать число между 100-199 200-299 300-399 и 400-499 для каждого из потоков соответственно. Однако, когда я передаю свой параметр interv, который представляет собой тип struct с двумя значениями int, я получаю что-то совершенно другое на другой стороне. Например, когда я отправляю 100 и 199, я получаю 0 вместо 199 и -13216 вместо 100. Я не уверен, в чем именно проблема, вот мой код:

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

#define NUM_THREADS 4
int sum; /* global variable shared by thread(s) */
pthread_mutex_t counter_lock = PTHREAD_MUTEX_INITIALIZER;


int cmpfunc (const void * a, const void * b)
{
   return ( *(int*)a - *(int*)b );
}

typedef struct interval {
    int min;
    int max;
} interval;

void *runner(struct interval *param); /* threads call this function */
/*
 * 
 */
int main(int argc, char *argv[]) {
    pthread_t workers[NUM_THREADS];
    interval *interv;
    interv->max = 199;
    interv->min = 100;
    /* create the thread */
    printf("min = %d max = %d n",interv->min,interv->max);
    for (int i = 0; i < NUM_THREADS; i  ) {
        printf("min = %d max = %d n",interv->min,interv->max);
        pthread_create(amp;workers[i],NULL,runner,amp;interv);
        interv->min  = 100;
        interv->max  = 100;
        /* wait for the thread to exit */
        pthread_join(amp;workers[i],NULL);
    }
    printf("sum = %dn",sum);
    return (0);
}

/* The thread will begin control in this function */
void *runner(struct interval *param) {
    int n, array[100], list_sum, counter;
    printf("min = %d max = %d n",param->min,param->max);
    for (int i; i < 100; i  ) {
        n = rand() % (param->max   1 - param->min)   param->min;
        array[i] = n;
        list_sum  = n;
    }
    qsort(array, 100, sizeof(int), cmpfunc);
    for (int i; i < 100; i  ) {
        counter  = 1;
        if (counter == 10) {
            counter = 0;
        }
    }
    pthread_mutex_lock(amp;counter_lock);
    sum  = list_sum;
    pthread_mutex_unlock(amp;counter_lock);
    pthread_exit(0);
}
 

ОБНОВЛЕНО:
Таким образом, я не получил ожидаемого результата при компиляции программы, поэтому я переписал большую часть своего кода. Хотя теперь, опять же, я получаю какое-то странное поведение, и я не уверен, почему.

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

#define NUM_THREADS 1
#define NUM_ELEMENTS 10
//Sum computed buy the background thread
int total = 0;
int counter = 0;

struct sum_runner_struct {
    int min;
    int max;
    int array[NUM_ELEMENTS];
    int answer;
};

//Thread function to generate a sum of 0 to N
void* runner(void* arg) {
    struct sum_runner_struct *arg_struct = (struct sum_runner_struct*) arg;
    int n, sum;
    for (int i = 0; i<NUM_ELEMENTS; i  ) {
        n = rand()%(arg_struct->max   1 - arg_struct->min)   arg_struct->min;
        printf("%d ",n);
        arg_struct->array[i] = n;
    }
    printf("n");
    for (int i = 0; i<NUM_ELEMENTS; i  ) {
        sum = sum   arg_struct->array[i];
        printf("%d ", arg_struct->array[i]);
        counter  = 1;
        if (counter == 10) {
            printf("n");
            counter = 0;
        }
    }
    printf("Sum: %dn",sum);
    arg_struct->answer = sum;
    pthread_exit(0);
}

int main(int argc, char **argv) {
    int INTERVALS[4][2] = {{100,199},{200,299},{300,399},{400,499}};
    struct sum_runner_struct args[NUM_THREADS];

    // Launch threads
    pthread_t tids[NUM_THREADS];

    for (int i = 0; i < NUM_THREADS; i  ) {
        args[i].min = INTERVALS[i][0];
        args[i].max = INTERVALS[i][1];
        //Create attributes
        pthread_attr_t attr;
        pthread_attr_init(amp;attr);

        //Create Thread
        pthread_create(amp;tids[i], amp;attr, runner, amp;args[i]);

    }

    //Wait until thread is done its work
    for (int i = 0; i < NUM_THREADS; i  ) {
        pthread_join(tids[i], NULL);
        printf("Sum of thread %d is %dn", i, args[i].answer);
        total  = args[i].answer;
    }
    printf("Sum is %dn", total);
}
 

Прежде чем вы прокомментируете мой генератор случайных чисел, я знаю, что на данный момент это не лучшее решение, но это не моя проблема. Моя проблема в том, что когда я добавляю числа в массив для потока, я получаю число, которое больше на 6 целых чисел. Я не уверен, почему это происходит.

Например, когда я запускаю программу с одним потоком для генерации 10 элементов, я получаю что-то вроде этого:

 133 143 162 129 100 108 152 156 156 119 
133 143 162 129 100 108 152 156 156 119 
Sum: 1364
Sum of thread 0 is 1364
Sum is 1364

RUN SUCCESSFUL (total time: 57ms)
 

Обратите внимание, что я напечатал массив дважды, поэтому существует две строки одного и того же массива. Как вы можете видеть (я думаю, я правильно их сложил), если вы добавите числа в массив, вы получите 1358, а не 1364. Я не уверен, что вызывает это.

Комментарии:

1. Прототип вашей функции должен быть void *runner(void *param); .

2. ПРИМЕЧАНИЕ: я думаю, что, возможно, я нашел проблему, но, похоже, не могу найти решение. Когда я отправляю аргумент interv, я понимаю, что отправляю amp;interv, который является указателем на указатель, поэтому значения могут отличаться. Но когда я удаляю amp;, я просто получаю СБОЙ ЗАПУСКА (значение выхода 1, общее время: 1 сек)

3. Вы никогда не выделяете память для interv .

4. не уверен, что это вызывает проблему, потому что за пределами функции runner все, кажется, работает нормально, я получаю правильные значения для min и max, когда я печатаю их вне функции, но внутри функции цифры становятся смешными.

5. Это неопределенное поведение, поэтому вполне возможно, что оно работает в main, а не в функции.

Ответ №1:

Хорошо, я нашел проблему, я точно не знаю почему, но когда я инициализирую int n, sum; по какой-то причине значение sum инициализируется равным 6. Кто-нибудь может объяснить, почему это происходит?