Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.05.26;
Скачать: [xml.tar.bz2];

Вниз

По поводу потоков...   Найти похожие ветки 

 
tovSuhov   (2003-05-15 11:36) [0]

Господа, может кто разъяснит, в чем была ошибка.
Суть вот в чем - в программе создаю объекты - наследники от (TThread). Причем один поток - это некий Менеджер, который в свою очередь создает n потоков - Рабочих.
Так вот, в Менеджере перед созданием потока-Рабочего я динамически (new)выделяю буфер, указатель на этот буфер передаю рожденному потоку и оправляю его "работать". После отработки поток заносит в этот буфер полученные в процессе работы данные.
Теперь самое интересное - когда создается только один Рабочий - все проходит тип-топ. Если их несколько, то программа вываливается с ошибками типа "BORLNDMM - ошибка доступа". В процессе отладки выяснил, что возникает она только тогда, когда Рабочие пишут в этот самый буфер.

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

Проблему обошел следующим образом - в Менеджере жду завершения работы всех рожденных потоков, и потом последовательно от каждого из них "сливаю" данные.

Интересует чисто теоретический аспект - какие могут быть причины некорректной работы описанного выше алгоритма?

С уважением, Сергей.


 
Dms   (2003-05-15 11:40) [1]

попробуй перейти на D7


 
Palladin   (2003-05-15 11:45) [2]

проблема одновременного доступа к данным, больше ничего...
кто знает чего ты там написал до этого... кода нет... больше добавить нечего...


 
evvcom   (2003-05-15 11:56) [3]

У меня менеджер сидит в основном потоке, т.е. там же, где и вся рисовательно-отзывающаяся часть. Менеджер не требует много времени для своей работы, так какой тогда смысл выносить его в отдельный поток?
Далее код создания и завершения рабочего потока также выполняется в основном. Итоговые данные из внутренних структур переписываются в основные в завершающем коде потока. Это гарантирует синхронизацию. И лишь кое-где в Execute у меня возникала необходимость обращаться к основным данным и тоже вроде никто другой не должен был к ним обращаться. Тоже были некоторые проблемы. Пришлось до минимума сократить подобные обращения, а где не было возможности использовал объекты синхронизации. Проблемы исчезли.


 
tovSuhov   (2003-05-15 12:02) [4]

Так а что подразумевать по одновременным доступом к данным?
Хорошо, приведу пример кода (правда на С++)

Поток-Менеджер:
for...
{
char * _data = new char[my_size]; //выделяю буфер
TMyWorker * _worker = new TMyWorker(_data,my_size); // создаю поток, передаю указатель на буфер
_worker->Resume(); // запускаю поток
}

Поток-Рабочий, метод Execute:
{
....
выполняется работа
....
memcpy(_data_ptr(указатель, котрый был передан в конструктор),(локальный буфер),(размер локального буфера));
//размер локального буфера либо 0, либо тот,что был передан в конструктор
};

Все. Так вот когда поток один - все ОК. Иначе глючит. По-моему никакого одновременного доступа к данным нет, или я ошибаюсь?


 
evvcom   (2003-05-15 12:11) [5]

Трудно судить по куску кода. Попробуй хотя бы ввести объекты синхронизации. Исчезнет ошибка - значит однозначно собака здесь порылась.


 
Palladin   (2003-05-15 12:13) [6]

а поток твой в этот _data пишет что нибудь по дороге исполнения?


 
clickmaker   (2003-05-15 12:15) [7]

Очевидно, выделение памяти типа new перехватывается борландовским MM. Попробуй использовать GlobalAlloc или HeapAlloc


 
tovSuhov   (2003-05-15 12:25) [8]

To Palladin:
Нет, не пишет. Сваливает только в конце работы.

To clickmaker: Я тоже подозреваю, что собака порылась в борландовом ММ. Но не понимаю каким образом.


 
clickmaker   (2003-05-15 12:29) [9]

А обязательно юзать этой самый borlandmm? Не включай юнит ShareMem в свой проект и все дела. А используй АПИшные ф-ии, какие - я уже писал


 
Alexander1966   (2003-05-15 13:28) [10]

Попробуй для создания потоков использовать BeginThread


 
Palladin   (2003-05-15 13:43) [11]


> Сваливает только в конце работы.

а если в конце исполнения сливают два потока (три и более)?
уж не борятся ли они друг с другом за место в буффере?


 
Verg   (2003-05-15 13:47) [12]

А какая связь между


> new TMyWorker(_data, my_size);


и


> memcpy(_data_ptr(указатель, котрый был передан в конструктор),(локальный
> буфер), (размер локального буфера));


??

Где гарантия того, что первый >= второго?

Или чего-то не договариваешь.



 
Verg   (2003-05-15 13:51) [13]

Я хотел спросить: локальный буфер ты выделяешь динамически в execute потока?


 
panov   (2003-05-15 17:36) [14]

Попробуй все-таки критические секции ввести...
Скорее всего, BorlandMM и твои потоки работают с одним участком памяти одновременно... Так мне кажется.


 
tovSuhov   (2003-05-15 18:41) [15]

Я выделяю память, указатель на нее передаю в поток. Внутри потока эту память чем-то заполняю.
Подверждаю следующие вещи:
1. Все потоки пользуются каждый своим буфером.
2. В буфер поток либо не пишет ничего, либо пишет ровно столько байт, сколько под него выделялось.

Так вот, вопрос - ТЕОРЕТИЧЕСКИ - могут возникнуть ошибки при таком подходе или нет? Оставим глюки реализации вне темы.


 
panov   (2003-05-15 20:35) [16]

>tovSuhov (15.05.03 18:41)

Я бы не дал рук на отсечение, что при использовании BorlandMM проблем не будет.


 
Palladin   (2003-05-15 21:30) [17]

Да могут, именно та которую я тебе в начале описал, как уже сказал panov © (15.05.03 17:36) при использовании каких либо общих вещей для множества потоков работают с критическими секциями



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2003.05.26;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.007 c
4-83788
Saska
2003-03-24 13:09
2003.05.26
GetSystemTime


6-83646
acsoft
2003-03-26 06:50
2003.05.26
Нажатие кнопки на HTML-странице в TWebBrowser


1-83545
andrey_pst
2003-05-13 17:37
2003.05.26
---|Ветка была без названия|---


7-83758
ed
2003-03-25 23:42
2003.05.26
флоп


1-83570
Ler
2003-05-12 16:34
2003.05.26
Ну Очень простой вопрос !!! (кол-во строк в лейбле )





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский