Многопоточность
От: demidov2  
Дата: 11.04.05 11:19
Оценка:
Работаю с классом TThread. Создал динамически 5 потоков. (th1 = new TMyThread(true); и.т.д) Каждый поток должен работать с ListView на главной форме. Для проверки каждый поток сначала добавляет строку в ListView с "?", а через 5 сек — в эту же строку ThreadID и индекс строки. В первые четыре строки ThreadID и индекс строки не пишутся, далее нормально, но внизу один "?" болтается. Выглядит так:
? ?
? ?
? ?
? ?
1501 4
988 5 и.т.д
Почему? Нужна ли здесь Критическая секция? Как вообще действовать в этом случае (несколько одинаковых потоков работают с ListView)?
void __fastcall TMyThread::Execute()
{
FreeOnTerminate = true;
for(int i = 0; i < 60; i++)
{
if(Terminated) break;
Synchronize(OnStartCheck);
Sleep(5000);
Synchronize(Result);
}
}
void __fastcall TMyThread::Result()
{
ListView1 = Form1->ListView1;
ListView1->Items->Item[Index]->Caption = IntToStr(ThreadID);
ListView1->Items->Item[Index]->SubItems->Strings[0] = IntToStr(Index);
}
void __fastcall TMyThread::OnStartCheck()
{
ListView1 = Form1->ListView1;
li1 = ListView1->Items->Add();
li1->Caption = "?";
li1->SubItems->Add("?");
Index = li1->Index; //запоминаем индекс созданой строки
}
Re: Многопоточность
От: Softwarer http://softwarer.ru
Дата: 11.04.05 11:33
Оценка:
Здравствуйте, demidov2, Вы писали:

D>Почему?


Путем тщательного анализа ситуации и оценочного моделирования я пришел к гипотезе, что используемый Вами Index — глобальная переменная, общая для всех потоков.

D>Нужна ли здесь Критическая секция?


Хм. Полагаю, теоретически она могла бы исправить этот эффект — ценой превращения "фиктивной многопоточности" (когда потоки работают строго по очереди) в "сериализированную многопоточность" (когда поток запускается не раньше, нежели предыдущий полностью отработает).

D>Как вообще действовать в этом случае (несколько одинаковых потоков работают с ListView)?


Как правило — завести объект-диспетчер, который (с помощью той же критической секции) умеет принимать вызовы из разных потоков и который работает с ListView.
Re[2]: Многопоточность
От: demidov2  
Дата: 11.04.05 12:04
Оценка:
Спасибо. Index объявлена в TMyThread. Видимо, в каждом потоке она своя.
Re: Многопоточность
От: Аноним  
Дата: 11.04.05 16:18
Оценка:
Единственное, что должен знать поток о форме — это ее хендл (HWND).
Когда надо что-то сделать с формой — делай PostMessage (именно Post..., а не Send...) со своим собственным MessageID
Форма должна уметь принимать лишь принимать этот MessageID и перерисовывать себя соответсвенно. Сколько потоков, что они делают — форме дложно быть по барабану.

Возможно, придется немного пересмотреть архитектуру. Но это к лучему. Помни, первична не форма, первичны данные. А их хранить можно в виде класса или record — это уже на выбор.
И, конечно, критическая секция при обращении к этим данным со стороны любого потока.
Re: Многопоточность
От: Аноним  
Дата: 12.04.05 06:08
Оценка:
Здравствуйте, demidov2, Вы писали:
D>void __fastcall TMyThread::Execute()
D>{
D> FreeOnTerminate = true;
D> for(int i = 0; i < 60; i++)
D> {
D> if(Terminated) break;
D> Synchronize(OnStartCheck);
D> Sleep(5000);
D> Synchronize(Result);
D> }
D>}
D> Нужна ли здесь Критическая секция?
При работе через Synchronize Критическая секция не нужна. Но, как Вам уже заметили, Index должен быть полем класса TMyThread;
Re[2]: Многопоточность
От: Аноним  
Дата: 13.04.05 16:30
Оценка:
Здравствуйте, Аноним, Вы писали:

А>При работе через Synchronize Критическая секция не нужна. Но, как Вам уже заметили, Index должен быть полем класса TMyThread;


Простите за резкость , но Synchronize() — это вреднейший из методов, придуманных Borland
Вреднейший в плане понимания "многопоточного программирования". Его использование в 99% ведет к неэффективному разделу времени выполнения.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.