FreeBasic
Главная
Вход
Регистрация
Пятница, 29.03.2024, 03:49Приветствую Вас Гость | RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 2
  • 1
  • 2
  • »
Форум » Freebasic » Вопросы по языку FreeBasic » Многопоточность (Как организовать передачу массивов в потоки и прием массивов)
Многопоточность
TimurARДата: Среда, 06.12.2017, 18:57 | Сообщение # 1
Рядовой
Группа: Пользователи
Сообщений: 14
Репутация: 0
Статус: Offline
Пожалуйста помогите разобраться. 
Общая задача примерно такая.
- читаем блоками данные из первого файла в массив
- через процедуру производим манипуляции с данными массива и сохраняем полученный результат в другой массив
- сохраняем полученный массив во второй файл
Блоки обрабатываются самостоятельно и на друг друга не влияют
Единственно в каком порядке они читаются из первого файла в таком порядке результат записывается во второй файл
Скорость обработки блоков данных довольно значительная, по этому для ускорения обработки данных хотелось бы применить многопоточность

Пробовал использовать конструкцию "handles(i) = ThreadCreate(@Procedura,parametr)
но "parametr" вроде согласно справки может быть только указателем
если оба массива определяем в структуру, то из-за указателя на структуру как передавать значения в массив
при этом есть глобальный массив из которого внутри процедуры читаются данные, но можно ли использовать в потоках глобальные переменные
Или лучше использовать конструкцию" handles(i) = ThreadCall Procedura(m1(),m2(),tlock), где "Dim tlock As Any Ptr", но в справке также указано что бы не использовать глобальные переменные
 
DarkDemonДата: Среда, 06.12.2017, 19:41 | Сообщение # 2
Полковник
Группа: Друзья
Сообщений: 188
Репутация: -2
Статус: Offline
Цитата TimurAR ()
но можно ли использовать в потоках глобальные переменные

Можно. Главное не писать одновременно из нескольких потоков в один массив одни данные поверх других.
А если требуется разграничить доступ используем mutex-ы.

Цитата TimurAR ()
Единственно в каком порядке они читаются из первого файла в таком порядке результат записывается во второй файл

Попробуйте сделать четырёх поточную прогу. Т.е. читаем 4 блока в 4 разных массива.
Далее создаём 4 потока и каждому потоку передаём указатель на соотв. массив(в threadcreate переменная parametr).
После этого ждём завершения отработки всех четырёх потоков и записываем обработанные данные в другой файл.
Далее процесс повторяем.
 
TimurARДата: Среда, 06.12.2017, 21:59 | Сообщение # 3
Рядовой
Группа: Пользователи
Сообщений: 14
Репутация: 0
Статус: Offline
для уточнения всех нюансов я попробую написать упрощенный тестовый код
и на этом примере разобрать

Добавлено (06.12.2017, 21:59)
---------------------------------------------
"Вот упрощенный рабочий код
Dim Pfile1 As String*260
Dim Pfile2 As String*260
Dim As Integer i,moi
Dim bsim As UByte

Dim m1(0 To 10) As UByte
Dim m2(0 To 10) As UByte
Dim Shared m3(0 To 10) As UByte

Const MAX_THREADS = 4
Dim Shared As Any Ptr ttylock

Data 13,11,7,9,3,5,19,17,27,23
For i=1 To 10
Read m3(i)
Next

Sub Proced(m1() As UByte,m2() As UByte,ByVal moi As Integer)
Dim i As Integer

For i=1 To 10
m2(i)=(m1(i)*moi+m3(i)) Mod 256
Next

End Sub

Open "File1.txt" For Binary Access Read As #1 'файл содержит 40 байт
Open "File2.txt" For Binary Access Write As #2

While EOF(1)=0

moi=1
While Eof(1)=0 And moi<10
Get #1,,bsim
m1(moi)=bsim
moi=moi+1
Wend

Proced(m1(),m2(),moi)
For i=1 To 10
Put #2,,m2(i)
Next

Wend

Close #1
Close #2

'=======
'Вот код с попыткой многопоточности, но что делать с переменными передаваемые процедуре не совсем понятно
Dim Pfile1 As String*260
Dim Pfile2 As String*260
Dim As Integer i,moi
Dim bsim As UByte

Dim m1(0 To 10) As UByte
Dim m2(0 To 10) As UByte
Dim Shared m3(0 To 10) As UByte

Const MAX_THREADS = 4
Dim Shared As Any Ptr ttylock
Dim As Any Ptr handles(0 To MAX_THREADS-1)

Data 13,11,7,9,3,5,19,17,27,23
For i=1 To 10
Read m3(i)
Next

Sub Proced(m1() As UByte,m2() As UByte,ByVal moi As Integer)
MutexLock ttylock

Dim i As Integer
For i=1 To 10
m2(i)=(m1(i)*moi+m3(i)) Mod 256
Next

MutexUnlock ttylock
End Sub

Open "File1.txt" For Binary Access Read As #1
Open "File2.txt" For Binary Access Write As #2

While EOF(1)=0

ttylock = MutexCreate()

For i=0 To MAX_THREADS-1
moi=1
While Eof(1)=0 And moi<10
Get #1,,bsim
m1(moi)=bsim
moi=moi+1
Wend

handles(i) = ThreadCreate(@Proced,m1(),m2(),moi) 'как передать и принять параметры в процедуру?

Next

For i As Integer = 0 To MAX_THREADS-1
If handles(i) <> 0 Then
ThreadWait(handles(i))
End If
Next

MutexDestroy(ttylock)

For i=1 To 10
Put #2,,m2(i)
Next

Wend

Close #1
Close #2


Сообщение отредактировал TimurAR - Среда, 06.12.2017, 22:05
 
WQДата: Среда, 06.12.2017, 22:03 | Сообщение # 4
Полковник
Группа: Проверенные
Сообщений: 215
Репутация: 7
Статус: Offline
Цитата TimurAR ()
если оба массива определяем в структуру, то из-за указателя на структуру как передавать значения в массив

Например
Код
Type anytype
   As String a(Any)
End Type

Sub anysub(value As anytype Ptr)   
   Dim As anytype value2 = *value
   ? value2.a(0)
   ? value2.a(1)
   ? value2.a(2)
End Sub

Dim value1 As anytype
ReDim value1.a(2)

value1.a(0) = "aaaaaaaaaaa"
value1.a(1) = "bbbbbbbbbbb"
value1.a(2) = "ccccccccccc"

ThreadCreate(Cast(Any Ptr,@anysub), @value1)

Sleep


Цитата TimurAR ()
при этом есть глобальный массив из которого внутри процедуры читаются данные, но можно ли использовать в потоках глобальные переменные
Если эти массивы разные, и каждый поток обращается к своему массиву, то можно, хотя, в теории, может создать проблемы
Практически, например, я написал несколько программ, где применялся такой подход, проблем не возникало
 
TimurARДата: Среда, 06.12.2017, 22:20 | Сообщение # 5
Рядовой
Группа: Пользователи
Сообщений: 14
Репутация: 0
Статус: Offline
с передачей массива в процедуру будем пробовать. А с получением массива из процедуры?
В приведенном мной втором тестовом коде есть неточность
'=================
Dim Pfile1 As String*260
Dim Pfile2 As String*260
Dim As Integer i,moi,a
Dim bsim As UByte

Dim m1(0 To 10) As UByte
Dim m2(0 To 10,0 To 4) As UByte 'добавил второй параметр что бы различать массивы после потока
Dim Shared m3(0 To 10) As UByte

Const MAX_THREADS = 4
Dim Shared As Any Ptr ttylock
Dim As Any Ptr handles(0 To MAX_THREADS-1)

Data 13,11,7,9,3,5,19,17,27,23
For i=1 To 10
Read m3(i)
Next

Sub Proced(m1() As UByte,m2() As UByte,ByVal moi As Integer,ByVal ii As Integer)
MutexLock ttylock

Dim i As Integer
For i=1 To 10
m2(i,ii)=(m1(i)*moi+m3(i)) Mod 256
Next

MutexUnlock ttylock
End Sub

Open "File1.txt" For Binary Access Read As #1
Open "File2.txt" For Binary Access Write As #2

While EOF(1)=0

ttylock = MutexCreate()

For i=0 To MAX_THREADS-1
moi=1
While Eof(1)=0 And moi<10
Get #1,,bsim
m1(moi)=bsim
moi=moi+1
Wend

handles(i) = ThreadCreate(@Proced,m1(),m2(),moi,i) 'как передать и принять параметры в процедуру?

Next

For i As Integer = 0 To MAX_THREADS-1
If handles(i) <> 0 Then
ThreadWait(handles(i))
End If
Next

MutexDestroy(ttylock)
For a=0 To 3
For i=1 To 10
Put #2,,m2(i,a)
Next
Next

Wend

Close #1
Close #2


Сообщение отредактировал TimurAR - Среда, 06.12.2017, 22:28
 
DarkDemonДата: Четверг, 07.12.2017, 00:55 | Сообщение # 6
Полковник
Группа: Друзья
Сообщений: 188
Репутация: -2
Статус: Offline
Цитата TimurAR ()
с передачей массива в процедуру будем пробовать

Вы создаёте себе сложности. Объявите массив глобально, в поток уходит один параметр при его создании,
засовываете туда указатель. По указателю с массивом можно делать всё, что угодно.
Простые алгоритмы требуют простых решений. Мозги нужно впрягать тогда, когда задача сложна.
Не изнашивайте свою бошку просто так, она не вечная.
Сами подумайте, вы пытаетесь организовать универсальную конвейерную обработку, а в требованиях у вас
"в каком порядке они читаются из первого файла в таком порядке результат".
Чисто теоретически конечно можно поделить файл на кол-во требуемых кусков, организовать структуру в памяти
где будет храниться состояние этих кусков и работать конвейером, считывая по указателю и записывая по указателю,
но это сложнее(и код уже будет необслуживаемым, а через месяц вы его откроете и припухнете), зачем вам этот
геморрой?
 
haavДата: Четверг, 07.12.2017, 08:43 | Сообщение # 7
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Не знаю, все ли я правильно понял, если что извиняюсь заранее. Если посмотреть на пример, то таким способом скорости точно не добьешься и не важно в одном потоке или нескольких. Важно понять где узкое горлышко. А оно в данном случае в чтении файла. Более или менее нормальным алгоритм будет выглядеть так:

1) Считать весь файл целиком в отдельно выделенную область. То есть не как в примере побайтно, а сразу весь файл. Для этого открываем файл , получаем его размер, выделяем память согласно этому размеру и считываем. Что то вроде этого:

Код
#include "file.bi"

Dim As Byte Ptr bPtr ' общий указатель на данные файла

dim as Integer f1 , f2  , ifLen

f1 = FreeFile

f2 = FreeFile

Open "File1.txt" For Binary Access Read As #f1

Open "File2.txt" For Binary Access Write As #f2

ifLen = FileLen("File1.txt")

bPtr = Allocate(ifLen)

Get #f1,,*bPtr,ifLen

Close


2) В памяти проводим все манипуляции , можно и в потоках. Мьютексы в данном случае не нужны, поскольку в потоках будут обрабатываться разные ячейки памяти.

2a) Делим длину файла на нужное кол-во частей. Например если файл размером 1000 байт, то поделив на 10 частей , мы отправляем в поток указатель на каждую часть типа bPtr+0 , bPtr+100 , bPtr + 200 , и т.д. Однако я думаю, что размер файла заранее неизвестен , поэтому лучше создать структуру вроде такой:

Код
Type TData
   
   As Byte Ptr bPtr ' указатель на часть данных
   
   As Long iLen ' длина этих данных
   
End Type


и уже деля общую длину на определенное кол-во байт , заполнять структуру с указанием адреса и длины каждого куска. Затем указатель на структуру отправлять в поток. Придется выделять память под каждую структуру перед отправкой указателя в многопоточную процедуру , а в самой процедуре можно освобождать память указателя.

3) Сохраняем в файл опять же весь блок данных целиком


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
TimurARДата: Четверг, 07.12.2017, 19:31 | Сообщение # 8
Рядовой
Группа: Пользователи
Сообщений: 14
Репутация: 0
Статус: Offline
Цитата haav ()
Важно понять где узкое горлышко.
ЭЭЭ Замерял время на базовом коде и обработка блоков данных заняла в 1000 раз больше времени по сравнению с чтением и записью файла. Поэтому хотел обработку блоков провести параллельно.

Добавлено (07.12.2017, 18:51)
---------------------------------------------

Цитата haav ()
Считать весь файл целиком в отдельно выделенную область. Т
Мысль такая была, беспокоит загружаемый объем. Возможно придется обрабатывать объем данных около 1Гбита

Добавлено (07.12.2017, 18:53)
---------------------------------------------

Цитата DarkDemon ()
вы пытаетесь организовать универсальную конвейерную обработку
Вообщем то да пытаюсь

Добавлено (07.12.2017, 19:07)
---------------------------------------------
Прошу прощения. Приведенный тестовый код не базовый, он просто содержит некоторую структуру базового кода.
Спасибо за советы, а можно все таки вписать поточную обработку в приведенный код.
Может быть параметры процедуры "m1(),m2(),moi,i" засунуть в структуру, то можно будет их передать в процедуру и получить обратно. ИЛИ может лучше использовать "Threadcall".

Добавлено (07.12.2017, 19:09)
---------------------------------------------

Цитата DarkDemon ()
через месяц вы его откроете и припухнете
Было дело, с другими программами.
Поэтому чуть ли не в каждой строчке уже написаны комментарии
А что делать. базовый код написан и работает, но медленно.

Добавлено (07.12.2017, 19:31)
---------------------------------------------
На обработку одного мегобита приходится примерно двадцать секунд на среднем компе

 
haavДата: Четверг, 07.12.2017, 20:01 | Сообщение # 9
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Цитата TimurAR ()
Мысль такая была, беспокоит загружаемый объем. Возможно придется обрабатывать объем данных около 1Гбита


Хмм... Размах однако smile Но это в любом случае не помешает использовать предложенное мною. Разве только вместо обычного чтения\записи файлов, я бы тогда использовал бы мэпирование. С другой стороны, если все устраивает кроме обработки данных, то я бы использовал структуру и записывал бы туда "m1(),m2(),moi,i" . m1() и m2() отправлял бы как указатели , ну то есть что-то типа:

Код

type tData

m1 as byte ptr
m2 as byte ptr
moi as integer
i as integer

end type

dim as tData ptr TPtr = new tdata
TPtr->m1 = @m1(0)
TPtr->m2 = @m2(0)
TPtr->moi = moi
TPtr->i = i

ThreadCreate(@Proced , TPtr)


Писал от руки прямо в браузере, если что не суди строго. Можно и с Threadcall все это замутить, хотя я эту функцию в реальных программах ни разу не проверял. В самой процедуре обращение к m1 и m2 будет не с круглыми скобками , а с квадратными (вместо m1(5) нужно будет писать m1[5]).


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
DarkDemonДата: Вторник, 12.12.2017, 15:35 | Сообщение # 10
Полковник
Группа: Друзья
Сообщений: 188
Репутация: -2
Статус: Offline
Цитата TimurAR ()
около 1Гбита


Неужели не будет 125 Мб оперативы? Шёл 2017 год... У меня на втором пне было 192 Мб оперативы...
 
TimurARДата: Пятница, 15.12.2017, 22:36 | Сообщение # 11
Рядовой
Группа: Пользователи
Сообщений: 14
Репутация: 0
Статус: Offline
один знакомый написал прогу и грузил файл с данными объемом 300 Мбайт
Кода я не видел но прога грузила комп прилично
(на работе до недавнего времени комп имел вшивые 1Гбайт оперативы)
вопрос грузить не грузить память философский, возможно придется оптимизировать многопоточость под какой нибудь контролер
лучше сэкономить память тем более с кодом практически все получилось
результат выложу попозже
к слову

"В самой процедуре обращение к m1 и m2 будет не с круглыми скобками , а с квадратными (вместо m1(5) нужно будет писать m1[5]"

Возникла потребность в двухмерном массиве
В справке указано
При индексировании ' 2-мерного ' указателя (т.е. T Ptr Ptr), Первый (крайний слева) индекс применяется перед вторым: например,
Pt[I1][I2] = *(Pt[I1] + I2) = *(*(Pt + I1) + I2)
Вот такой способ обращения не работает "Pt[I1][I2]"
Неужели придется одномерный массив делать с псеводо индексацией
Подскажите как сделать
 
haavДата: Суббота, 16.12.2017, 15:27 | Сообщение # 12
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Цитата TimurAR ()
Вот такой способ обращения не работает "Pt[I1][I2]"
Неужели придется одномерный массив делать с псеводо индексацией
Подскажите как сделать


Можно так попробовать:

Код
Dim As Integer i1 = 10 ,i2 = 20 , i3 = 2, i4 = 6

Dim p(i1,i2) As Integer

Dim p1 As integer Ptr

p1 = @p(0,0)

p(i3,i4) = 50

?  *(p1+ i2 * i3 + i4 + i3)

sleep


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
TimurARДата: Вторник, 19.12.2017, 20:30 | Сообщение # 13
Рядовой
Группа: Пользователи
Сообщений: 14
Репутация: 0
Статус: Offline
Есть промежуточный результат

Dim Pfile1 As String*260
Dim Pfile2 As String*260
Dim As Integer a,moi,i
Dim iii As Integer Ptr
Dim As Integer bb1,bb2
Dim As Double ttt

Dim bsim As UByte

Const M_T = 20
Const M_B = 10
Dim Shared m1(0 To 200) As UByte
Dim Shared m2(0 To 200) As UByte
Dim Shared m3(0 To 10) As UByte
Dim Shared idl(0 To 20) As Integer

Dim Shared As Any Ptr ttylock
Dim As Any Ptr handles(0 To M_T-1)
'- - - - - - - - - - - - - - - - - - - - - - -
Sub Proced(ByVal ii As Integer)
Dim a As Integer

For a=1 To idl(ii)
m2(a+ii*10)=(m1(a+ii*10)+1) Mod 256
'Print Chr(m1(i+ii*10));';" ";
Next
'Print 
Sleep 500
End Sub
'- - - - - - - - - - - - - - - - - - - - - - -
Open "File2.txt" For Binary Access Read As #1
Open "File3.txt" For Binary Access Write As #2

While EOF(1)=0'- - - - - -

ttt=timer
For i=0 To 19
moi=1
While Eof(1)=0 And moi<11
Get #1,,bsim
m1(moi+i*10)=bsim
moi=moi+1
Wend
iii=i
If moi>1 Then bb1=i:idl(i)=moi-1:handles(i) = ThreadCreate(@Proced,iii) 
Next

For i = 0 To 19
If handles(i) <> 0 Then
ThreadWait(handles(i))
End If
Next
Print Timer-ttt

For i = 0 To 19
For a=1 To idl(i)
'Print idl(i)
If bb1>=i And a<=idl(i) Then Put #2,,m2(a+i*10)

Next
Next

Wend'- - - - - - - - - -

Close #1
Close #2
Print "Gotovo"
Sleep 5000

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

Добавлено (19.12.2017, 20:30)
---------------------------------------------
Почему результат есть но не всегда и как его стабилизировать

 
haavДата: Среда, 20.12.2017, 07:11 | Сообщение # 14
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Цитата TimurAR ()
В данном коде я обращался на прямую к глобальному массиву но требуемый результат получается очень редко, после нескольких повторных запусков программы (через указатели и структуру тоже делал, но внятного результата почему то не получил, наверно где то ошибся)

Добавлено (19.12.2017, 20:30)
---------------------------------------------
Почему результат есть но не всегда и как его стабилизировать


Таким образом ничего путного не получится. Глобальные переменные в потоках портятся. В лучшем случае на выходе будет неверный результат, в худшем программа будет вылетать. Если использовать мьютексы, то скорость может оказаться даже ниже , чем в одном потоке. Я же написал выше в сообщении как можно передать данные в поток. Не должно быть никаких общих данных для всех потоков, в каждый поток нужно загружать свои копии данных.


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
TimurARДата: Понедельник, 08.01.2018, 20:40 | Сообщение # 15
Рядовой
Группа: Пользователи
Сообщений: 14
Репутация: 0
Статус: Offline
пробую еще раз через структуру

Эээ... Долго не было, был занят другими делами.
Вот вроде получилось через указатели, но результат не однозначный.
Некоторые блоки обрабатываются неверно.

Код
Dim Pfile1 As String*260
Dim Pfile2 As String*260
Dim As Integer a,moi,i,c
Dim As UByte b
Dim iii As Integer Ptr
Dim As Integer bb1,bb2
Dim As Double ttt

Dim bsim As UByte

Const M_T = 20
Const M_B = 10

Dim As UByte m1(0 To 200)
Dim As UByte m2(0 To 200)
Dim As UByte m3(0 To 200)
Dim As Integer idl(0 To 20)
Dim As Integer ii

Type tM
    mm1 As UByte Ptr
    mm2 As UByte Ptr
    mm3 As UByte Ptr
    idlm As Integer Ptr
    iim As Integer
End Type

Dim As tM Ptr tMM = New tM

tMM->mm1=@m1(0)
tMM->mm2=@m2(0)
tMM->mm3=@m3(0)
tMM->idlm=@idl(0)
tMM->iim=ii

Dim Shared As Any Ptr ttylock
Dim As Any Ptr handles(0 To M_T-1)

Data 13,11,7,9,3,5,19,17,27,23
For a=1 To 10
    Read m3(a)
Next

'=====================================================
Sub Proced(MM As tM Ptr)
'MutexLock ttylock
    Dim As Integer a, b,c

    b=MM->iim
    c= MM->idlm
    For a=1 To c
        MM->mm2[a+b*10]=( MM->mm1[a+b*10] ) Mod 256
    Next
    Sleep 500
'MutexUnLock ttylock
End Sub
'=====================================================
Open "File1.txt" For Binary Access Read As #1
Open "File2.txt" For Binary Access Write As #2

While EOF(1)=0'- - - - - -

'ttylock = MutexCreate()'- - - - - - - - - - - -
    ttt=timer
    For i=0 To 19
        moi=1
        While Eof(1)=0 And moi<11
            Get #1,,bsim
            tMM->mm1[moi+i*10]=bsim
            moi=moi+1
        Wend
        tMM->iim=i
        If moi>1 Then bb1=i:tMM->idlm[i]=moi-1:handles(i) = ThreadCreate(@Proced,tMM)
    Next

    For i = 0 To bb1
        If handles(i) <> 0 Then
            ThreadWait(handles(i))
        End If
    Next
    Print Timer-ttt
'MutexDestroy(ttylock)'- - - - - - - - - - - - -

    For i = 0 To tMM->iim
        c=tMM->idlm
        For a=1 To c
            b=tMM->mm2[a+i*10]
            If bb1>=i And a<=tMM->idlm Then Put #2,,b
        Next
    Next
Wend'- - - - - - - - - -

Close #1
Close #2
Print "Gotovo"
Sleep


Перечитав сообщения выше, стало понятно что надо сделать как в данном совете

Цитата haav ()
2a) Делим длину файла на нужное кол-во частей. Например если файл размером 1000 байт, то поделив на 10 частей , мы отправляем в поток указатель на каждую часть типа bPtr+0 , bPtr+100 , bPtr + 200 , и т.д. Однако я думаю, что размер файла заранее неизвестен , поэтому лучше создать структуру вроде такой:

Код
Type TData

As Byte Ptr bPtr ' указатель на часть данных

As Long iLen ' длина этих данных

End Type

и уже деля общую длину на определенное кол-во байт , заполнять структуру с указанием адреса и длины каждого куска. Затем указатель на структуру отправлять в поток. Придется выделять память под каждую структуру перед отправкой указателя в многопоточную процедуру , а в самой процедуре можно освобождать память указателя.

3) Сохраняем в файл опять же весь блок данных целиком


Видоизменил программу так

Код
Dim Pfile1 As String*260
Dim Pfile2 As String*260
Dim As Integer a,moi,i,c
Dim As UByte b
Dim iii As Integer Ptr
Dim As Integer bb1,bb2
Dim As Double ttt

Dim bsim As UByte

Const M_T = 20
Const M_B = 10

Dim As UByte m1(0 To 200)
Dim As UByte m2(0 To 200)
Dim As UByte m3(0 To 200)
Dim As UByte idl(0 To 20)
Dim As Integer ii

Type tM
    mm1 As UByte Ptr
    mm2 As UByte Ptr
    mm3 As UByte Ptr
    idlm As UByte Ptr
    iim As Integer Ptr
End Type

Dim As tM Ptr tMM = New tM

Dim Shared As Any Ptr ttylock
Dim As Any Ptr handles(0 To M_T-1)

Data 13,11,7,9,3,5,19,17,27,23
For a=1 To 10
    Read m3(a)
Next

'=====================================================
Sub Proced(MM As tM Ptr)
'MutexLock ttylock
    Dim As Integer a, b,c
    
    b=MM->iim
    c=MM->idlm[0]
    For a=0 To c-1
       MM->mm2[a]=(MM->mm1[a]) Mod 256
    Next
    Sleep 500
'MutexUnLock ttylock
End Sub
'=====================================================
Open "File1.txt" For Binary Access Read As #1
Open "File2.txt" For Binary Access Write As #2

While EOF(1)=0'- - - - - -

    'ttylock = MutexCreate()'- - - - - - - - - - - -
    ttt=Timer
    
    'читаю файл
    For i=0 To 19
       moi=1
       While Eof(1)=0 And moi<11
          Get #1,,bsim
          m1(moi-1+i*10)=bsim
          moi=moi+1
       Wend
       ii=i
       If moi>1 Then bb1=i:idl(i)=moi-1':handles(i) = ThreadCreate(@Proced,tMM)'
    Next
    
    'ставлю указатель на область памяти и отправляю в поток
    For i=0 To bb1
  
       tMM->mm1=@m1(i*10)
       tMM->mm2=@m2(i*10)
       tMM->idlm=@idl(i)
       tMM->iim=@ii
  
       If idl(i)>0 Then handles(i) = ThreadCreate(@Proced,tMM)
    Next
    
    'Жду завершения потоков
    For i = 0 To bb1
       If handles(i) <> 0 Then
          ThreadWait(handles(i))
       End If
    Next
    Print Timer-ttt
    'MutexDestroy(ttylock)'- - - - - - - - - - - - -

    'Записываю в файл
    For i = 0 To bb1
       c=idl(i)
       For a=1 To c
           b=m2(a-1+i*10)
           If bb1>=i And a<=c Then Put #2,,b
       Next
    Next
Wend'- - - - - - - - - -

Delete tMM
Close #1
Close #2
Print "Gotovo"
Sleep


Но что то делаю не так. Часть данных испорчена. Ясно что указатель надо создавать перед отправлением в поток и удалять после потока, но как это сделать непонятно.

Как привязать архив сюда?


Сообщение отредактировал TimurAR - Вторник, 09.01.2018, 20:42
 
Форум » Freebasic » Вопросы по языку FreeBasic » Многопоточность (Как организовать передачу массивов в потоки и прием массивов)
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск: