WedX - журнал о программировании и компьютерных науках

Pthread не работает, когда используется определенное количество потоков

Я столкнулся со странным явлением: моя программа на C не работает с определенным количеством потоков, например. 8.

Когда я отлаживаю с помощью «fprintf», я обнаружил, что проблема возникает при создании pthreads:

298 /* work for each thread */
299 void* work(void *t)
300 {
301   long tid;
302   tid = (long)t;
303   fprintf(stderr, "In thread %lu\n", tid);
304
...
368   pthread_exit((void*)t);
369 }

513 /* main function */
514 int my_main(struct Params params)
515 {
...
      pthread_t* threads;
      threads = malloc(threads_num * sizeof(pthread_t));
574   long t;
575   int rc;
576   for (t=0; t<threads_num; t++)
577   {
578     fprintf(stderr, "create %lu\n", t);
579     rc = pthread_create(&threads[t], NULL, work, (void*)t);
580     if(rc)
581     {
582       printf("ERROR: return code from pthread_creat() is %d\n", rc);
583       exit(-1);
584     }
585   }
...
599   for(t=0; t<threads_num; t++)
600     pthread_join(threads[t], NULL);
...
615   return 0;
616 }

Результаты выглядят так:

create 0
create 1
create 2
create 3
create 4
create 5
In thread 0
In thread 3
In thread 4
create 6
In thread 1
In thread 2
In thread 5
create 7
In thread 6
Segmentation fault

Какие потенциальные проблемы могут возникнуть для потока 7? Есть предположения?

Другая информация может быть полезна: Коды хорошо работают на моем MacBook Pro с GCC в качестве компилятора. Проблемы здесь в тех случаях, когда я компилирую их на некоторых серверах Linux (openSUSE) с GCC.


  • Это настоящий код? Возможно, изначально вы написали: fprintf(stderr, "p%d\n", (int)t);? 31.12.2013
  • @Shahbaz Это настоящий, а не тот, который вы написали. 31.12.2013
  • Я не думаю, что что-то происходит, кроме того, что вы запускаете потоки (p2) быстрее, чем они планируются и запускаются (p3) 31.12.2013
  • Простое объяснение состоит в том, что вы не ждете, пока эти потоки завершатся, и настоящая функция main() завершится до того, как они получат шанс запуститься. 31.12.2013
  • Обычно у вас не возникает проблем с pthreads, создающими 8 потоков. Поэтому, пожалуйста, покажите нам минимальную, но полную программу, которая раскрывает поведение. Причиной ошибки может быть недостаточный размер массива threads или преждевременный выход из main, но по нескольким кускам сложно сказать. 31.12.2013
  • @ Ханс Пассант, да, это так. OP - либо pthread_join ваши темы, либо pthread_exit ваши основные. 31.12.2013
  • Shahbaz, Duck, Hans Passant, Inspired, я только что обновил свои коды, чтобы сделать их более понятными. 31.12.2013
  • @JackWM, в следующий раз, пожалуйста, опубликуй правильный код. Теперь вопрос сильно изменился! 31.12.2013
  • @Шахбаз Ты прав. Извините за изменение. 01.01.2014
  • Еще многое может быть причиной segfault в исключенном коде, представленном ... областями. Было бы полезно опубликовать полную программу, в которой все еще есть проблема. 01.01.2014
  • В приведенном выше коде нет ничего плохого. На самом деле он компилируется и работает нормально с разными значениями threads_num. Ошибка сегментации возникает где-то еще в коде. Я предлагаю запустить это под отладчиком и проверить трассировку стека. 01.01.2014
  • @selbie Я забыл кое-что упомянуть: коды хорошо работают на моем MacBook Pro с gcc в качестве компилятора. Проблема, о которой я писал здесь, связана с некоторыми серверами, на которых работает openSUSE. 01.01.2014

Ответы:


1

Спасибо за все ответы и комментарии!

Я нашел источник этой странной ошибки сегментации.

В некоторых других частях кода я загружал числа с плавающей запятой в некоторые массивы. Однако я по ошибке использовал malloc( sizeof(int) * length). Раньше я использовал тип float, так как float и int имеют одинаковый размер, эта ошибка не проявлялась в моих более ранних версиях кодов. Но недавно я обновил типы с float на double, что приводит к такому странному поведению.

Извините за размещение кодов, которые не связаны с источником ошибки. Я не ожидал, что эта ошибка приведет к странному поведению pthread.

01.01.2014

2

Я подозреваю, что вы переполняете массив threads. Поскольку вы не показали, где это объявлено, я не могу быть уверен. Обычно первое, что я делаю, пытаясь отладить ошибку сегментации, — запускаю gdb. RMS написал очень хорошее введение в использование символьного отладчика для отслеживания ошибок сегментации. GDB может обрабатывать такие необычные вещи, как переключение между потоками, и останавливаться прямо на инструкции, вызвавшей segfault, без какой-либо ручной установки точек останова.

31.12.2013
  • Спасибо, нмайклс. Я добавил объявление к вопросу. Но так быть не должно. Так как он работает для большого количества потоков, например 90 потоков. 01.01.2014
  • Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: [email protected]