C / Linux Threads: подсчитать, сколько появлений '1' в числах от 1 до n - PullRequest
0 голосов
/ 06 апреля 2020

Таким образом, из чисел от 1 до n я должен вычислить, сколько встречается '1' di git. Например: если n равно 11, общее число равно 4 (1, 10, 11). Мое назначение говорит, что я должен использовать темы для этого. Это то, что я написал до сих пор:

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

typedef struct {
    int from;
    int to;
} th_struct;

void *thread_function(void *param){
    th_struct *st = (th_struct *) param;
    int count = 0;
    int nr;

    for(int i = st->from; i <= st->to; i++){
        nr = i + 1;
        while(nr != 0 ){
            if (nr % 10 == 1)
                count++;
            nr /= 10;
        }
    }

    return (void *) (long) count;
}

int main(int argc, char **argv)
{
    int threads, n, count = 0, result;
    sscanf(argv[1], "%d", &n);
    sscanf(argv[2], "%d", &threads);

    th_struct info[threads];
    pthread_t tid[threads];

    for(int i = 0; i < threads; i++){
        if(i == 0)
            info[0].from = 0;
        else
            info[i].from = info[i - 1].to + 1;

        info[i].to = info[i].from + n / threads - 1;

        if(i < n / threads)
            info[i].to++;

        pthread_create(&tid[i], NULL, thread_function, &info[i]);
    }

     for(int i = 0; i < threads; i++){
         pthread_join(tid[i], (void**)&result);
         count += (int) (long) result;
     } 

    printf("%d\n", count);
}

Первый аргумент командной строки - n, а второй - количество потоков. Для n, равного 11, выход должен быть 4. Но если я подключу 11 1 (n = 11, nr потоков = 1), выход будет 5 (вместо 4). Если я подключаю 11 2 (два потока), вывод равен 9. Выход должен быть одинаковым, независимо от того, сколько потоков у меня есть.

Я проверил следующий код, и он работает. Он правильно вычисляет число '1' (следующее то же самое, что и в функции "thread_function_ выше", только что адаптированной для тестирования):

int function(int n){
    int count = 0;
    int nr;

    for(int i = 0; i <= n; i++){
        nr = i + 1;
        while(nr != 0 ){
            if (nr % 10 == 1)
                count++;
            nr /= 10;
        }
    }

    return count;
}

Так что проблема связана с потоками (я думаю). Так как это моя первая программа с потоками, я не знаю, в чем проблема. Спасибо!

1 Ответ

0 голосов
/ 06 апреля 2020

У вас есть несколько проблем:

  1. Неправильные диапазоны ввода:

    info[0].from = 0;
    ...
    if(i < n / threads)
         info[i].to++;
    

    Должно быть:

    info[i].from = 1;
    ...
    if (n % 2 == 1 && i + 1 == threads)
        info[i].to++;
    
  2. Обработка неверного диапазона:

    nr = i + 1;

    Должно быть:

    nr = i;

  3. Получение неверного результата. i изменяет свое значение при выполнении итерации для объединения потоков и для l oop выполняется больше раз, чем предполагалось:

    pthread_join(tid[i], (void**)&result);

    Должно быть:

    void* result;
    pthread_join(tid[i], &result);
    
...