#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. Кто-нибудь может объяснить, почему это происходит?