爬虫 7 :多线程和多进程

1、线程和进程
程序:一个应用可以当做一个程序
进程:一个正在运行的程序可以当做一个进程。进程拥有独立的资源
线程:程序中独立运行的代码段。
一个程序至少有一个进程,一个进程至少有一个线程。
多线程定义:多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。
可以提高CPU的利用率
多线程是通过提高cpu利用率来实现的。

2、线程的五种状态
当cpu调度该线程,就变成运行状态,运行状态的线程才是工作的线程。—》如果线程阻塞就变成阻塞状态,阻塞结束,阻塞状态的线程先要回到就绪状态,继续等待cpu调度他,进入运行状态。
在这里插入图片描述
小结:
(1) 每一个线程一定会有一个名字,如果用户没有指定名字,系统会为线程指定一个名字(Thread-1/2/3…)。
(2) 当线程的run方法结束的时候该线程完成任务。
(3) 我们程序员无法控制线程调试的顺序。CPU根据当时的状态自行决定。
多线程线程不安全问题主要是多个线程对公共数据的操作时,会造成公有数据的混乱。

3、多线程和多进程:
1、进程是系统进行资源分配和调试的一个独立单位。
线程是进程的一个实体,是CPU调用和分派的基本单位,它是比进程更小的能独立运行的基本单位。
线程自己基本上不拥有系统资源,但是它可以与同属于一个进程的其它线程共享进程所拥有的全部资源。
2、区别:
多线程比多进程的并发程度相对较高。线程划分尺度更小,可以最大程度上提高cpu的利用

率。
但是多线程中每个线程公用进程中的资源,容易造成对公共资源的使用混乱,也容易造成死

锁。
3、优缺点:
线程和进程在使用上各有优势和缺点:线程的执行开销小,但不利于资源的管理和保存。进

程正好相反。

4、多线程的优点:
程序逻辑和控制方式复杂;
所有线程可以直接共享内存和变量;
线程方式消耗的总资源比进程方式好。
多线程缺点:
每个线程与主程序共用地址空间,受限于2GB地址空间;
线程之间的同步和加锁控制比较麻烦;
一个线程的崩溃可能影响到整个程序的稳定性;
多进程优点:
每个进程互相独立,不影响主程序的稳定性,子进程崩溃没关系;
通过增加CPU,就可以容易扩充性能;
每个子进程都有2GB地址空间和相关资源,总体能够达到的性能上限非常大 。
多线程缺点:
逻辑控制复杂,需要和主程序交互;
需要跨进程边界,如果有大数据量传送,就不太好,适合小数据量传送、密集运算 多进程

调度开销比较大。
在实际开发中,选择多线程和多进程应该从具体实际开发来进行选择。最好是多进程和多线程结合

,即根据实际的需要,每个CPU开启一个子进程,这个子进程开启多线程可以为若干同类型的数据进行处理。
5.死锁:
两种情况:
第一种:同一个线程先后对同一个资源调用两次锁

	# g_num = 0
	# def func1(num):
	#     global g_num
	#     for i in range(num):
	#         lock.acquire() #加锁
	#         g_num+=1
	#         lock.release() #释放锁
	#     print('--in func1--g_num=%d'%g_num)
	# def func2(num):
	#     global g_num
	#     for i in range(num):
	#         lock.acquire()  # 加锁
	#         g_num+=1
	#         lock.release()  # 释放锁
	#     print('--in func2--g_num=%d'%g_num)
	# lock = Lock() #创建锁
	# t1 = Thread(target=func1,args=(1000000,))
	# t2 = Thread(target=func2,args=(1000000,))
	# t1.start()
	# t2.start()
	第二种:线程A获得了锁1,线程B获得了锁2,这时线程A调用lock试图获得锁2,结果是需

要挂起等待线程B释放锁2,而这时线程B也调用lock试图获得锁1,结果是需要挂起等待线程A释放锁1,于是线

程A和B都在等待对方释放自己才释放,从而造成两个都永远处于挂起状态,造成死锁

import time,threading
printer_lock = Lock()#创建打印机锁
paper_lock = Lock() #创建简历锁

class Printer(Thread):
    def run(self):
        # pass
        print('---Printer start')
        paper_lock.acquire()
        time.sleep(1)
        print('编写简历1')
        printer_lock.acquire()
        print('正在使用打印机1')
        printer_lock.release()
        paper_lock.release()
        print('---Printer end')
class Paper(Thread):
    def run(self):
        print(threading.current_thread().name)
        # pass
        print('---Paper start')
        printer_lock.acquire()
        print('正在使用打印机2')
        time.sleep(1)
        paper_lock.acquire()
        print('编写简历2')
        paper_lock.release()
        printer_lock.release()
        print('---Paper end')
if __name__ == '__main__':
    t1 = Printer()
    t2 = Paper()
    t1.start()
    print(threading.current_thread().name)
    t2.start()

6.消息队列开启多线程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值