Re[6]: Многопоточность + синхронизация + как бороться?
От: HAS Россия hasalex@mail.ru
Дата: 08.03.06 07:09
Оценка:
Здравствуйте, npo_mir, Вы писали:

_>On Sun, 05 Mar 2006 19:35:26 +0600, HAS <36274@users.rsdn.ru> wrote:


>>> Это нужно смотреть что у вас в ParsePage(Thread->Page);

>> на данный момент там PushPage(Addresses[random(AddressCounts)]); т.е. просто добавление страницы в очередь

_>Хм... кстати, может менеджер памяти не знает про многопоточность и начинают лезть глюки с памятью?


по-идее должен знать... пишу всо под Builder 5.0... кстати, очень часто проект подвисает с ошибкой типа "что-то там сломалось в Borlandbk50.bpk". За что отвесает этот пакет?

и еще: какие моменты не может уловить CodeGuard? потому как с точки зрения кода — везде все очищается как надо, но если забить большой цикл по созданию и убиванию
этого менеджера (порядка > 1000) то память жрется неплохо, а CodeGuard молчит ((


_>По поводу зависаний: если зависло и при этом не есть процессорное время, то дело явно в deadlock.


_>В любом случае это нужно все прогнать под отладчиком.


заманался гонять, такое ощущение, что отладчик глюкаво работает, потому как очень часто выкидывает на код, где в принципе ничего быть не должно (там даже многопоточности нету)

>>> Зачем? Какой вам тогда вообще смысл в многопоточности если вы ее накорню прибиваете.

>> почему?

_>Не, если функция состоит всего из одной простой операции, то все нормально. Но если там что-нить посложнее, то получится что остальные потоки вместо того чтобы делать свое дело будут тупо ждать пока функция завершит свою работу, что не есть хорошо.


поток только качает страницу и скидывает её в файлик

_>Как я уже говорил, синхронизировать доступ нужно не к функциям, а к разделяемым ресурсам. В вашем случае — это та очередь с которой вы работаете.


пример работы с этой очередью:

void __fastcall THttpDownloadManager::Update()
{
EnterCriticalSection(&CS);
try
{
#define MaxThreadCount 20
while ((FAddressWaiting > 0 || FAddressDownloaded > 0) && FAddressDownloading < MaxThreadCount && !FPause && !FTerminate)
{
TAddressInfo *Info = NULL;
for (int i=FAddresses->Count-1; i>=0 && FAddressDownloading < MaxThreadCount; --i)
{
Info = (TAddressInfo*)FAddresses->Items[i];
if (Info == NULL) continue;
switch (Info->State)
{
case AS_INORDER: {
if ((FAddressWaiting > 0) && (FAddressDownloading < MaxThreadCount)) DownloadPage(Info);
break;
};
case AS_ERROR: {
++FAddressError;
--FAddressDownloaded;
++FAddressReady;
Info->State = AS_IDLE;
DoAddressStateChange(Info);
break;
};
case AS_DOWNLOADED: {
--FAddressDownloaded;
++FAddressReady;
if (Info->Recursive)
ParsePage(Info);
Info->State = AS_READY;
DoAddressStateChange(Info);
break;
};
};
};
};
if (FAddressReady == FAddressCount | FTerminate)
{
FState = (FTerminate) ? DM_TERMINATE: DM_READY;
if (FOnFinished != NULL) FOnFinished(NULL);
};

}__finally
{
LeaveCriticalSection(&CS);
};
};

---
при этом DownloadPage создает и запускает поток, ParsePage — выдирает из страницы ссылки и добавляет их в очередь через PushPage (pushpage заключен между EnterCriticalSection & LeaveCriticalSection). Чтоздесь не так?

_>--

_>Всего хорошего, Слава.
_>ICQ: 197577902
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.