我正在开发一个简单的多线程网络爬虫。我使用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);
答案 0 :(得分:6)
我为每个线程定义了关键部分
他们必须使用相同的关键部分才能正确锁定。如果它们都有自己的关键部分,那么锁只适用于自己。
我假设您的帖子在TPageCrawl
,您可以传入通话中的关键部分:
TPageCrawl.Create(critical,@threads,sqldb.Fs('adresa'),index,sqldb)
然后在您的主题搜索过程中,您可以根据需要EnterCriticalSection()
和LeaveCriticalSection()
。
答案 1 :(得分:4)
我为每个线程定义了关键部分,包括主线程。
这不是它的工作原理。您需要拥有一个共享的临界区对象。每个线程必须使用相同的关键部分才能使序列化工作。您需要在关键部分对象和需要保护的资源之间建立一对一的关系。
关键部分对象一次只能由一个线程拥有,这有助于保护共享资源不被同时访问。