Multithreading 主螺纹临界截面

Multithreading 主螺纹临界截面,multithreading,delphi,Multithreading,Delphi,我正在开发一个简单的多线程网络爬虫。我正在使用sqlite数据库存储将被扫描的URL。我只有一个数据库句柄。问题是主线程查询数据库以生成新线程。线程正在访问相同的句柄,但主线程也在访问 我已经为每个线程定义了关键部分,包括主线程。但是,如果线程也处于关键部分,则主线程将继续执行代码eaven 下面是一些代码: CreateDb; InitializeCriticalSection(critical); index := 0; repeat if threads <

我正在开发一个简单的多线程网络爬虫。我正在使用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);
CreateDb;
初始化关键部分(关键);
指数:=0;
重复
如果螺纹的URL'+IntToStr(索引));
urlcount:=sqldb.rowcount;
对于i:=1到urlcount do
开始
WriteLn(sqldb.Fs('adresa'));
sqldb.next;
索引:=sqldb.Fi('id');
创建(@threads,sqldb.Fs('adresa'),index,sqldb)do;
如果螺纹=螺纹_MAX,则断裂;
结束;
离开关键部分(关键);
除了
离开关键部分(关键);
继续;
结束;
结束;
写(标志);
睡眠(1000);
直到(线程数=0)和(urlcount<1);
我已经为每个线程定义了关键部分

为了正确锁定,它们必须使用相同的临界截面。如果它们都有自己的临界段,那么锁只适用于它们自己

我假设您的线程位于
TPageCrawl
,您可以在调用中传递关键部分:

TPageCrawl.Create(critical,@threads,sqldb.Fs('adresa'),index,sqldb)
然后在线程进程中,您可以根据需要
进入CriticalSection()
离开CriticalSection()

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

为了正确锁定,它们必须使用相同的临界截面。如果它们都有自己的临界段,那么锁只适用于它们自己

我假设您的线程位于
TPageCrawl
,您可以在调用中传递关键部分:

TPageCrawl.Create(critical,@threads,sqldb.Fs('adresa'),index,sqldb)
然后在线程进程中,您可以根据需要
进入CriticalSection()
离开CriticalSection()

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

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

从:

临界段对象一次只能由一个线程拥有,这有助于保护共享资源不被同时访问

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

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

从:

临界段对象一次只能由一个线程拥有,这有助于保护共享资源不被同时访问


愚蠢的部分是,我使用共享的关键部分编写代码,但收到访问冲突并责怪共享的关键部分。曼尼,谢谢!愚蠢的部分是,我使用共享的关键部分编写代码,但收到访问冲突并责怪共享的关键部分。曼尼,谢谢!请注意,这些API调用被封装在
TCriticalSection
类中,这使得使用它们变得更加容易。还有
TMultiReadExclusiveWriteSynchronizer
可以满足更复杂的需求。我使用的是免费的pascal,我需要一个跨平台的解决方案,这样可以很好地工作。感谢againNote将这些API调用封装在
TCriticalSection
类中,这使使用它们变得更简单。还有
TMultiReadExclusiveWriteSynchronizer
可以满足更复杂的需求。我使用的是免费的pascal,我需要一个跨平台的解决方案,这样可以很好地工作。再次感谢