背景:运行一个爬虫,开了10个线程,每个线程先去爬取指定数量的代理作为自己的代理池,然后开始工作。
问题:下面是爬虫日志的两行,可以看到在第一行任务处等待了45秒,而这里不过是输出一条信息,十分不理解为什么等了这么长时间?日志中像这样动辄十几秒什么一两分钟的情形基本都发生在爬取代理的过程中,是否意味着这个任务的代码有问题?
15:57:50 INFO Thread-2 the proxy already in list, skip
15:58:35 INFO Thread-10 {'https': '117.170.28.178:8123'} download 2111 bytes in 0.75 seconds(average in 1 tries), need 10, available count: 7
思考:我理解python的多线程调度机制是完成了一条指令后,就可以调用其他线程了,并不是一定要等着这个指令得到了预期的结果,那么如果我的代码写的有问题也不至于影响他的调度吧。这个线程没有进展又不将CPU的使用权让渡出来,GIL为什么不剥夺这个线程的运行时间,总不至于是在等待某个程序块或者函数运行完毕吧。
Didapati masalah yang diterangkan terutamanya disebabkan oleh penggunaan SQLite yang tidak betul Reka bentuk sebelumnya adalah untuk membuka sambungan sehingga pengesahan semua ejen dalam kumpulan ejen selesai dan sejumlah ejen ditangkap sebelum menutupnya. sambungan, dan setiap kali Apabila menambah, mengubah suai atau memadam maklumat ejen, fail data ditulis, yang menyebabkan SQLite berbutir kasar dikunci untuk masa yang lama.
Selepas menemui masalah ini, kami mengoptimumkannya Selepas membaca ejen inventori pada permulaan sambungan baharu, kami segera menutup sambungan Selepas itu, semua data ejen baharu, dikemas kini dan dipadamkan disimpan sementara dalam pembolehubah kelas sehingga semua ejen yang diperlukan diperolehi Kemudian, buka sambungan baru, kemas kini data dengan executemany, kemudian tutup sambungan, selesaikan tugas yang dijadualkan, dan kelajuan akan meningkat.
Walau bagaimanapun, saya masih tidak faham mengapa dalam situasi asal, mekanisme penjadualan utas membenarkan utas yang disekat oleh pangkalan data sentiasa menduduki sumber dan bukannya menukar masa?
Jadi urutan anda disekat pada tahap menulis ke pangkalan data Memandangkan anda menggunakan
.sqlite
, izinkan saya memberi anda satu lagi kuasa purba untuk mempercepatkan operasi penulisan pangkalan data:Tiga kaedah digunakan untuk mempercepatkan
sqlite
kelajuan menulisMatikan penyegerakan cakera
Transaksi SQLite
laksanakan banyak sisipan kelompok
PS: Di samping itu, jika anda mempunyai memori yang mencukupi, anda boleh membuang fail pangkalan data ke dalam direktori
.tmpfs
, yang akan menghapuskan kesan I/O cakera (bersamaan dengan menulis terus dalam ingatan)