|  | 
 
 | 
| 
 | |||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны | 
|  | 
|  | Опции темы | Поиск в этой теме | Опции просмотра | 
| 
			 
			#1  
			
			
			
			
		 | |||
| 
 | |||
|  Два параллельных потока Приветствую, господа! Стоит такая задача: Записать содержимое таблицы в две сторонние БД. Эту задачу необходимо выполнять параллельно - запись в каждую БД в отдельном потоке. Каждый из потоков использует разные компоненты доступа, чтобы не мешать друг другу. Я написал код, который работает, однако как только запускается второй поток, первый становится на паузу и ждет, пока закончится второй. Мне же нужно, чтобы они отработали одновременно. [Класс потока] Код:  Tload = class(TThread)
      IBDB:TIBDataBase; 
      search:TIBQuery;
      tsearch,treport:TIBTransaction;
      import_pre:TIBDataset;
      import_delete,pre_delete:TIBSQL;
      memo:Tmemo; 
   public
    procedure Execute; override;
    procedure CreareSpec(db:string;memo:tmemo); //определяет в какую БД пишем, и в какой компонент выводим логи
  
  end;//тут я динамически создаю компоненты, и их свойста для объекта потока Код: self.memo:=memo; IBDB:=tibdatabase.Create(form1); ibDB.DatabaseName:=db; Процедура Execute Код: procedure Tload.Execute; var f:textfile; begin inherited; assignfile(f,'c:\'+memo.Name+'.txt'); rewrite(f); memo.Clear; try каждая операция в цикле записывается в текстовый файл каждая пятитысячная операция (i mod 5000=0) выводится в соотвествующий memo. У каждого объекта потока он точно будет разный. в конце terminate В коде программы объявляю две переменные типа TLoad A1,A2:Tload; и вешаю на две кнопки запуск двух процессов первая кнопка Код: if ibdb.Connected=false then ibdb.Open; A1:=Tload.Create(true); A1.Priority:=tpNormal; A1.FreeOnTerminate:=true; A1.CreareSpec(db_path1,memo3); A1.Execute; Код: if ibdb.Connected=false then ibdb.Open; A2:=Tload.Create(true); A2.Priority:=tpNormal; A2.FreeOnTerminate:=true; A2.CreareSpec(db_path2,memo3); A2.Execute; Как я уже говорил, как только я запускаю второй поток, первый становится на паузу. Я почитал литературу, но так и не нашел ответа. Буду рад Вашей помощи. Админ: 2-х дневный бан за несоблюдение правил форума по оформлению кода. Последний раз редактировалось Admin, 04.09.2014 в 19:24. | 
| 
			 
			#2  
			
			
			
			
		 | |||
| 
 | |||
|   Он именно ожидает? Или вылетает? Если ожидает,то возможно критическая секция Последний раз редактировалось Heneken, 08.09.2014 в 13:42. | 
| 
			 
			#3  
			
			
			
			
		 | ||||
| 
 | ||||
|   А почему я тут не вижу ни одного вызова метода Synchronize()? | 
| 
			 
			#4  
			
			
			
			
		 | |||
| 
 | |||
|   Цитата: 
 | 
| 
			 
			#5  
			
			
			
			
		 | |||
| 
 | |||
|   только надо не  Код: A1.Execute; Код: A1.Resume; | 
| 
			 
			#6  
			
			
			
			
		 | ||||
| 
 | ||||
|  Это чо такое было? Цитата: 
 Там же обращения к VCL-объектам прямо в Execute()! Маленький копипаст-ликбез из умной книжки: Цитата: 
 | 
| 
			 
			#7  
			
			
			
			
		 | |||
| 
 | |||
|   Метод Synchronize нужен только тогда, когда происходит обращение к VCL (и не только к VCL) объектам, находящимся В ГЛАВНОМ ПОТОКЕ ПРИЛОЖЕНИЯ. В данном же случае все компоненты находятся в дополнительном потоке, так что с этим проблем быть не должно. Я бы грешил на какие-нить объекты синхронизации внутри самих компонентов доступа к БД. Но в таком случае тормозился бы второй поток, т.к. первый уже их занял. Так что тут, видимо, действительно дело в прямом вызове метода Execute, который, вообще-то, должен быть в секции protected, но ТСом перенесен в секцию public, что и позволило вызвать этот метод напрямую в основном потоке приложения, а не создавая дополнительный поток. ТС, поменяй вызов Execute на выов Resume и наступит тебе счастье  | 
| 
			 
			#8  
			
			
			
			
		 | ||||
| 
 | ||||
|   Цитата: 
  |