最近花了两个星期的时间来写了一份C
语言爬虫的作业,感觉还是学到了很多东西,包括惨痛的调试经验,所以这里和大家分享一下
1、为什么不用python来写爬虫?
上第一节课的时候,我就提出了这个问题,老师给了我一个无法反驳的理由:用C
语言写过爬虫的人可以解决用Python
写爬虫时遇到的底层网络问题,而用Python
写爬虫的人很难解决类似的问题。
仔细想想,好好挺有道理的【好吧,以上内容纯属杜撰~~~】
2、什么是libevent?
写到这里,我不得不去百度一下,为了节约大家的时间,这里我就直接从百度上粘了一段libevent
的简介:
libevent
是一个用C
语言的开发的、轻量级的开源高性能网络库,具有代码精炼、性能强大、跨平台以及基于事件驱动等多个特点,对于I/O
复用有良好的支持。
【以上内容纯属粘贴,可跳过】
3、什么是I/O复用?
用C
写过socket
程序的同学应该都知道,当建立一个socket
连接之后,我们就会使用write
和read
函数来进行函数发送或接收数据,一般情况下,我们都会使用阻塞模式的socket
,这就意味着当我们调用了write
或read
函数以后,我们必须等待全部数据发送或接收结束我们才能进行下一步操作。
这里初看没有什么问题,但事实并非如此:在阻塞模式下,我们只能使用一个线程来处理一个socket
,如果有 1000
个连接,我们就需要1000
个线程,对于普通的客户端程序而言,建立socket
的数量不会很多,这样的开发方式并没有太大问题。但是服务器端程序通常需要处理多个从客户端发起的socket
请求,线程越多意味着消耗的资源越多,这对于强调高性能的服务器是不能忍受的。
说了这么多,其实就是想指出非阻塞模式。顾名思义,程序不会因为write
和read
函数导致程序停止执行,相反,函数会马上返回结果,这个时候我们就可以干别的事去了。I/O
复用其实就是同时管理多个socket
连接,如果接收到某个socket
传递的数据,就把该数据交给对应的线程去处理,否者不进行任何操作。而libevent
所做的就是实现了一套基于I/O
复用的跨平台的高性能网络I/O
框架。
4、线程池
线程池,从字面上来理解就是多个线程并发运行。实际上,线程池做到了任务执行与线程管理的分离。在需要处理任务时,我需要做的只是往线程池插入一个任务,而线程管理则交由线程池内部来完成。在没有任务的时候,线程池中的每一个线程都处于等待状态,处于等待状态的线程处于阻塞状态,因而资源消耗极低。
【未完待续】