Обсуждение статьи тематического каталога: Многопотоковое программирование под Linux (threads linux gcc)Ссылка на текст статьи: http://www.opennet.me/base/dev/linux_threads.txt.html
sleep использовать не всегда хорошо. Есть более оптимальные решения. Например просыпаться в этом месте по сигналу.
У автора есть грубая ошибка!
в main создан указатель
>>DATA *arg;позднее он в цикле инициализируется объектом (тоже в main)
>> arg = new DATA;но удаляется объект почемуто из функций потоков
>> delete a; // удаляем свои данныепричем удаление происходит После разблокирования мутекса!
Так делать очень опасно!
можете легко прибить чужой объект или вычитать чужие данные (чтение тоже выполняется вне лока мутекса почемуто)Безопасные варианты:
1) создать массив указателей
DATA *arg[SIZE_I][SIZE_J]
и отдавать каждому потоку указатель на индивидуальный кусок памяти.
2)выполнять все операции с общей памятью только при заблокированном мутексе (тоесть в потоках чтение, модификация и освобождение общей памяти должно быть внутри общего pthread_mutex_lock(&lock)).
3) удалять объекты только в том потоке который их создал.Код статьи в качестве примера использовать не рекомендуется ибо в нем автор наступил на те грабли от которых по идее должен уберечь читателей.
>>//создаем поток для ввода
>>pthread_create(&thr[i+z], NULL, input_thr, (void *)arg);как я понял должны создаваться потоки для ввода каждого элемента матрицы, но
i=1,z=2 -- &thr[i+z] укажет на &thr[3]
i=2,z=1 -- &thr[i+z] укажет на &thr[3]>>//Ожидаем завершения всех потоков
>>//идентификаторы потоков хранятся в массиве
>>pthread_join(thr[i], NULL);при
i=3,z=3 -- &thr[i+z] укажет на &thr[6] и этот поток мы не ждем, т.к. size_i=4, правильно? соответственно и расчет данных для таких элементов будет "левым"?
Действительно имеет место несколько косяков.
1) При определении массива thr надо указывать количество элементов как SIZE_I*SIZE_J.
2) В циклах обращаться к элементам как i*SIZE_J+z
3) При переборе элементов массива соответственно должно быть написано for(int i = 0; i<SIZE_I*SIZE_J; ++i)
4) Как уже написал MordorSV действительно лучше создать массив указателей на данные и удалять его в том потоке в котором создавался