Здравствуйте!
У меня возникла проблема хранения бинарных данных в памяти программы. Я получаю в одном потоке бинарные данные. Передать их в другой поток можно через глобальную переменную, но за раз могу получить разное число этих данных и с одной глобальной переменной тут не справится. Можно через массив, но я не знаю какой тип установить, или может можно через структуру, но тут я вообще не знаю как делать. Помогите примером, пожалуйста.
Хранение бинарных данных в программе
Сообщений 1 страница 12 из 12
Поделиться111.04.2013 21:57:32
Поделиться211.04.2013 23:38:24
Выделяете требуемый объем памяти под данные, копируете их туда, а указатель передаете в другой поток.
В этом другом потоке, обрабатываете данные и освобождаете память.
Поделиться312.04.2013 15:53:15
Так это мне надо выделять память под каждые данные? Ну вот например в одном потоке я разбиваю бинарный файл на несколько частей(количество частей зависит от настроек пользователя). Как мне выделить память под каждую часть? И как потом передать на обработку ту часть, которую выбрал пользователь?
Поделиться412.04.2013 16:19:18
Так это мне надо выделять память под каждые данные?
Да. В первом потоке, выделяете память и копируйте туда данные.
Передаете указатель во второй поток, который обрабатывает данные и освобождает память.
Ну вот например в одном потоке я разбиваю бинарный файл на несколько частей
Посмотрите пример. http://pure-basic.narod.ru/forum_files/Hash.zip
В нем данные читаются из файла в одном потоке и передаются в несколько других потоков.
Поделиться512.04.2013 16:49:26
Посмотрите пример. http://pure-basic.narod.ru/forum_files/Hash.zip
А ну вот:
Structure InfoHash *Point Length.l Status.HashStatus EndStructure
Это структура, где *Point это память, а Length.l это ее размер?
А вот тут уже идет заполнение памяти
FileData()\Point = *Buffer FileData()\Length = Length
Значит не обязательно под каждую часть файла писать *MemoryID = AllocateMemory(1000) ?
Поделиться612.04.2013 17:50:13
Это структура, где *Point это память
Нет, это указатель на память.
А вот тут уже идет заполнение памяти
Нет. Это запись адреса памяти и ее размера в структуру текущего элемента списка.
Значит не обязательно под каждую часть файла писать *MemoryID = AllocateMemory(1000) ?
Обязательно. В коде процедуры ThreadFile() есть такие строки.
*Buffer = AllocateMemory(#BuffSize) If *Buffer
Собственно в *Buffer будет помещен указатель на память, потом туда запишутся данные.
If ReadFile_(hFile, *Buffer, #BuffSize, @Length, #Null)<=0
После чего, будет захвачен мьютекс, создан новый элемент в списке FileData(), в который запишутся указатель на память и размер памяти. Затем мьютекс будет освобожден и остальные потоки будут проинформированы что появились новые данные (вызов процедуры SendInfo()).
Поделиться712.04.2013 21:28:29
Обязательно. В коде процедуры ThreadFile() есть такие строки.
Ну в смысле там один раз объявляется. А потом в указатель который находится в структуре будут записываться данные из *Buffer. Правильно?
Поделиться812.04.2013 22:13:10
Ну в смысле там один раз объявляется.
Что один раз?
Память выделяется под каждую порцию данных.
Поделиться913.04.2013 00:18:06
Память выделяется под каждую порцию данных.
А как быть если неизвестно сколько частей будет?
Поделиться1013.04.2013 11:11:27
А как быть если неизвестно сколько частей будет?
Пример выше. Там заранее неизвестно сколько частей будет.
Поэтому и использован связанный список для хранения указателей на память каждой части.
Поделиться1113.04.2013 17:07:46
Если тот пример не понятен, то его можно упростить, взяв за основу код из справки. http://purebasic.com/documentation/thre … phore.html
Global Semaphore = CreateSemaphore() Global Mutex = CreateMutex() Global NewList Queue.i() Procedure Producer(Total) For i = 1 To Total Delay(Random(750) + 250) *mem = AllocateMemory(100) ; Выделили 100 байт под данные If *mem ; Тут копируем данные в память ; The queue access still needs a normal mutex lock to be thread-safe LockMutex(Mutex) FirstElement(Queue()) InsertElement(Queue()) Queue() = *mem UnlockMutex(Mutex) EndIf ; Signal that there is a new queue element SignalSemaphore(Semaphore) Next i EndProcedure If CreateThread(@Producer(), 30) For i = 1 To 30 ; wait for one element to be available WaitSemaphore(Semaphore) *Mem=0 ; display the queue state LockMutex(Mutex) ; remove head element from the queue LastElement(Queue()) *Mem=Queue() DeleteElement(Queue()) UnlockMutex(Mutex) If *Mem ; Обрабатываем данные. FreeMemory(*Mem) ; Освобождаем память. EndIf Next i EndIf
Поделиться1214.04.2013 20:46:18
Пётр
Спасибо, так понятней.