主线程中的关键部分

时间:2013-01-30 10:12:23

标签: multithreading delphi

我正在开发一个简单的多线程网络爬虫。我使用sqlite数据库来存储将被扫描的URL。我只有一个数据库句柄,问题是主线程查询数据库以生成新线程。线程访问相同的句柄但主线程还

我为每个线程定义了关键部分,包括主线程。但是如果一个线程也在一个关键部分,那么主线程就会继续执行代码eaven。

以下是一些代码:

  CreateDb;

  InitializeCriticalSection(critical);

  index := 0;

  repeat
   if threads < THREADS_MAX then
   begin
     EnterCriticalSection(critical);
     try
       sqldb.query('SELECT * FROM urls WHERE vizitat=0 AND id>' + IntToStr(index));
       urlcount:= sqldb.rowcount;

       for i:= 1 to urlcount do
       begin
         WriteLn(sqldb.Fs('adresa'));
         sqldb.next;
         index := sqldb.Fi('id');
         with TPageCrawl.Create(@threads,sqldb.Fs('adresa'),index,sqldb) do;
         if threads = THREADS_MAX then break;
       end;
       LeaveCriticalSection(critical);
     except
       LeaveCriticalSection(critical);
       Continue;
     end;
   end;

   Write(logo);
   Sleep(1000);
  until (threads = 0) and (urlcount  < 1);

2 个答案:

答案 0 :(得分:6)

  

我为每个线程定义了关键部分

他们必须使用相同的关键部分才能正确锁定。如果它们都有自己的关键部分,那么锁只适用于自己。

我假设您的帖子在TPageCrawl,您可以传入通话中的关键部分:

TPageCrawl.Create(critical,@threads,sqldb.Fs('adresa'),index,sqldb)

然后在您的主题搜索过程中,您可以根据需要EnterCriticalSection()LeaveCriticalSection()

答案 1 :(得分:4)

  

我为每个线程定义了关键部分,包括主线程。

这不是它的工作原理。您需要拥有一个共享的临界区对象。每个线程必须使用相同的关键部分才能使序列化工作。您需要在关键部分对象和需要保护的资源之间建立一对一的关系。

来自documentation

  

关键部分对象一次只能由一个线程拥有,这有助于保护共享资源不被同时访问。