Здравствуйте!
У меня возникла проблема хранения бинарных данных в памяти программы. Я получаю в одном потоке бинарные данные. Передать их в другой поток можно через глобальную переменную, но за раз могу получить разное число этих данных и с одной глобальной переменной тут не справится. Можно через массив, но я не знаю какой тип установить, или может можно через структуру, но тут я вообще не знаю как делать. Помогите примером, пожалуйста.
Хранение бинарных данных в программе
Сообщений 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
Пётр
Спасибо, так понятней.