Многопоточность
|
|
TimurAR | Дата: Среда, 06.12.2017, 18:57 | Сообщение # 1 |
Рядовой
Группа: Пользователи
Сообщений: 14
Статус: 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
Статус: Offline
| Цитата TimurAR ( ) но можно ли использовать в потоках глобальные переменные Можно. Главное не писать одновременно из нескольких потоков в один массив одни данные поверх других. А если требуется разграничить доступ используем mutex-ы.
Цитата TimurAR ( ) Единственно в каком порядке они читаются из первого файла в таком порядке результат записывается во второй файл Попробуйте сделать четырёх поточную прогу. Т.е. читаем 4 блока в 4 разных массива. Далее создаём 4 потока и каждому потоку передаём указатель на соотв. массив(в threadcreate переменная parametr). После этого ждём завершения отработки всех четырёх потоков и записываем обработанные данные в другой файл. Далее процесс повторяем.
|
|
| |
TimurAR | Дата: Среда, 06.12.2017, 21:59 | Сообщение # 3 |
Рядовой
Группа: Пользователи
Сообщений: 14
Статус: 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
Статус: 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
Статус: 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
Статус: Offline
| Цитата TimurAR ( ) с передачей массива в процедуру будем пробовать Вы создаёте себе сложности. Объявите массив глобально, в поток уходит один параметр при его создании, засовываете туда указатель. По указателю с массивом можно делать всё, что угодно. Простые алгоритмы требуют простых решений. Мозги нужно впрягать тогда, когда задача сложна. Не изнашивайте свою бошку просто так, она не вечная. Сами подумайте, вы пытаетесь организовать универсальную конвейерную обработку, а в требованиях у вас "в каком порядке они читаются из первого файла в таком порядке результат". Чисто теоретически конечно можно поделить файл на кол-во требуемых кусков, организовать структуру в памяти где будет храниться состояние этих кусков и работать конвейером, считывая по указателю и записывая по указателю, но это сложнее(и код уже будет необслуживаемым, а через месяц вы его откроете и припухнете), зачем вам этот геморрой?
|
|
| |
haav | Дата: Четверг, 07.12.2017, 08:43 | Сообщение # 7 |
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Статус: 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
Статус: 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
Статус: Offline
| Цитата TimurAR ( ) Мысль такая была, беспокоит загружаемый объем. Возможно придется обрабатывать объем данных около 1Гбита
Хмм... Размах однако Но это в любом случае не помешает использовать предложенное мною. Разве только вместо обычного чтения\записи файлов, я бы тогда использовал бы мэпирование. С другой стороны, если все устраивает кроме обработки данных, то я бы использовал структуру и записывал бы туда "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
Статус: Offline
| Цитата TimurAR ( ) около 1Гбита
Неужели не будет 125 Мб оперативы? Шёл 2017 год... У меня на втором пне было 192 Мб оперативы...
|
|
| |
TimurAR | Дата: Пятница, 15.12.2017, 22:36 | Сообщение # 11 |
Рядовой
Группа: Пользователи
Сообщений: 14
Статус: 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
Статус: 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
Статус: 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
Статус: Offline
| Цитата TimurAR ( ) В данном коде я обращался на прямую к глобальному массиву но требуемый результат получается очень редко, после нескольких повторных запусков программы (через указатели и структуру тоже делал, но внятного результата почему то не получил, наверно где то ошибся)
Добавлено (19.12.2017, 20:30) --------------------------------------------- Почему результат есть но не всегда и как его стабилизировать
Таким образом ничего путного не получится. Глобальные переменные в потоках портятся. В лучшем случае на выходе будет неверный результат, в худшем программа будет вылетать. Если использовать мьютексы, то скорость может оказаться даже ниже , чем в одном потоке. Я же написал выше в сообщении как можно передать данные в поток. Не должно быть никаких общих данных для всех потоков, в каждый поток нужно загружать свои копии данных.
Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
|
|
| |
TimurAR | Дата: Понедельник, 08.01.2018, 20:40 | Сообщение # 15 |
Рядовой
Группа: Пользователи
Сообщений: 14
Статус: 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 |
|
| |
|