Странные спорадические ошибки в самой тривиальной программе на C, связанной с pthreadsLinux

Ответить Пред. темаСлед. тема
Anonymous
 Странные спорадические ошибки в самой тривиальной программе на C, связанной с pthreads

Сообщение Anonymous »

Ниже приведен исходный код на языке C для тривиальной программы.
В программе есть основной цикл, в котором пользователю предлагается выбрать один из трех вариантов:
1- напечатать несколько text
2- выполнить некоторую работу (без побочных эффектов)
3- выйти из программы.
Если пользователь выбирает 2, то вызывается функция (с именем махинации), что представляет собой вычислительно затратную задачу, поддающуюся распараллеливанию. Эта функция использует pthreads, чтобы воспользоваться преимуществами многоядерной архитектуры ЦП, однако обратите внимание, что функция «махинации» обязательно «присоединяется» к каждому созданному потоку и не завершает работу до тех пор, пока не завершатся все рабочие потоки.
Многопоточный характер функции «махинации» должен быть полностью прозрачен для остальной части программы.
вот исходный код:

Код: Выделить всё

#include 
#include 
#include 
#include 
#include 
#include

int convert_to_integer(const char *str, int *outValue) {
if (str == NULL || outValue == NULL) return -1; // NULL pointer error

char *endptr;
errno = 0;
long temp = strtol(str, &endptr, 10);

if (errno == ERANGE && (temp == LONG_MAX || temp == LONG_MIN))
return -2; // Overflow or underflow
if (errno != 0 && temp == 0)
return -3; // Other conversion error
if (endptr == str)
return -4; // No digits were found
if (*endptr != '\0')
return -5; // Additional characters after number
if (temp > INT_MAX || temp < INT_MIN)
return -6; // Value out of int range

*outValue = (int)temp;
return 0; // Success
}

int get_int_from_stdin(int *target) {
if (target == NULL) return -1; // NULL pointer error

char input[64];
if (fgets(input, sizeof(input), stdin) == NULL)
return -2; // Reading error or EOF

// null-terminate the string if newline is found
size_t len = strlen(input);
if (input[len - 1] == '\n') {
input[len - 1] = '\0';
} else {
// Clear stdin buffer if input exceeded buffer length, to avoid leftover input affecting subsequent reads
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
if (len == sizeof(input) - 1) return -3; // Input too long
}

int value;
int result = convert_to_integer(input, &value);
if (result != 0) return result; // Propagate error code from conversion

*target = value;
return 0; // Success
}

void * thread_function(void * args) {
// this is work that will be done by threads
// notice there is no side effects and no interaction with
// stdout and stdin
// just waste a bunch of time
long x = 0;
for (int i = 0; i < 10000; i++) {
for (int j = 0; j < 1000000; j++) {
if (i %2 == 0) x++;
else x--;
}
}

return NULL;
}

void shenanigans(){
// run 7 different worker threads in parallel
printf("running tasks in parallel\n");
fflush(stdout); // flushing the output buffer doesn't do anything
//---- start of multithreading code
pthread_t threads[7];

// initiate 7 worker threads to do some work
for (int j = 0; j < 7; j++) pthread_create(&threads[j], NULL, thread_function, NULL);

// wait for all threads to finish
for (int j = 0; j < 7;  j++) pthread_join(threads[j], NULL);
// ---- end of multithreading code
printf("task finished...\n");
}

void print_junk(){
printf("Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n");
}

int main() {
while (1) {
printf("\nChoose an option from the following menu: \n");
printf("1- do some calculations\n");
printf("2- print some junk to standard output\n");
printf("3- exit...\n");
int choice;
int result = get_int_from_stdin(&choice);
if (result != 0) {
printf("Invalid input, try again\n");
continue;
}
if (choice == 1) {
// this function uses parallelism to get its job done faster
// but the parallelism ought to be completely transparent to the main function
shenanigans();
} else if (choice == 2) {
print_junk();
} else if (choice == 3) {
break;
} else {
printf("Invalid choice, try again\n");
}
}
return 0;
}

Когда я компилирую и выполняю этот код, я получаю несколько странных спорадических ошибок:
1-
В основном цикле, когда пользователь вводит опцию «1», я ожидаю, что строка «параллельное выполнение задач» немедленно появится на консоли, прежде чем основной поток заблокируется, ожидая завершения рабочих потоков. Тем не менее, это не всегда так. Много раз после того, как я ввожу «1» в консоль, программа перестает отвечать на запросы, поскольку рабочие потоки выполняют свою работу, и только через некоторое время я вижу, что «параллельное выполнение задач» печатается на console
2- по какой-то странной причине кажется, что когда основной поток ожидает завершения рабочих потоков, некоторые символы помещаются во входной буфер, вызывая плохие побочные эффекты в основной цикл, когда я пытаюсь прочитать выбор пользователя.
вот изображение, описывающее проблемы, о которых я говорю

Эти ошибки состояния гонки наиболее странны, потому что:
1 - нет ввода и вывода НУЛЯ в рабочих потоках.
2- нет НУЛЕВОЙ общей памяти или мутации глобального состояния между потоками.
Что мне здесь не хватает?

Подробнее здесь: https://stackoverflow.com/questions/784 ... g-pthreads
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Php-файл, вызывающий спорадические ошибки
    Anonymous » » в форуме Php
    0 Ответы
    37 Просмотры
    Последнее сообщение Anonymous
  • Valgrind: память по-прежнему доступна с помощью тривиальной программы с использованием
    Anonymous » » в форуме C++
    0 Ответы
    26 Просмотры
    Последнее сообщение Anonymous
  • Subprocess.Popen: процесс завершается при тривиальной ошибке
    Anonymous » » в форуме Python
    0 Ответы
    8 Просмотры
    Последнее сообщение Anonymous
  • Я получаю спорадические сбои с момента обновления Swift ModelContainer
    Anonymous » » в форуме IOS
    0 Ответы
    4 Просмотры
    Последнее сообщение Anonymous
  • PHP: pthreads не загружается на PHP 8.1
    Anonymous » » в форуме Php
    0 Ответы
    34 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Linux»