并发编程-03 23

1.进程

进程是资源分配的最小单位,线程是CPU调度的最小单位。每一个进程中至少有一个线程。

主进程中的线程称为主线程,其他开启的线程称为子线程

# 如何开启线程
from multiprocessing import Process

from threading import Thread


def task():
    print("子线程")


if __name__ == '__main__':
    t = Thread(target=task)
    t.start()
    print("主线程")

2.全局解释器锁(GIL)

1. python代码在解释器中执行,cpython解释器, pypy解释器

2. GIL锁在解释器中存在,他只在cpython解释器中,pypy解释器中不存在

3. 起一个垃圾回收线程,起一个正常执行的线程,垃圾回收还没回收完毕,另一个线程可能会抢占资源

4. 设置了一把全局解释器锁(GIL锁),有了这把锁,就保证同一时刻,只能有一个线程执行,
    只要线程想执行,那么,就必须拿到这把GIL锁

5. 如果是io密集型:选择线程

6. 如果是计算密集型:选择进程

3.线程与进程的区别

通过漫画了解线程和进程

可以归纳为以下4点:

  1. 地址空间和其它资源(如打开文件):进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。
  2. 通信:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。
  3. 调度和切换:线程上下文切换比进程上下文切换要快得多。
  4. 在多线程操作系统中,进程不是一个可执行的实体。

4.通过threading.Thread类创建线程

1. 创建线程的方式一

from threading import Thread
import time
def sayhi(name):
    time.sleep(2)
    print('%s say hello' %name)

if __name__ == '__main__':
    t=Thread(target=sayhi,args=('nick',))
    t.start()
    print('主线程')

2. 创建线程的方式二

from threading import Thread
import time
class Sayhi(Thread):
    def __init__(self,name):
        super().__init__()
        self.name=name
    def run(self):
        time.sleep(2)
        print('%s say hello' % self.name)


if __name__ == '__main__':
    t = Sayhi('nick')
    t.start()
    print('主线程')

Thread类的其他方法

hread实例对象的方法:

isAlive():返回线程是否活动的。
getName():返回线程名。
setName():设置线程名。
threading模块提供的一些方法:

threading.currentThread():返回当前的线程变量。
threading.enumerate():返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
threading.activeCount():返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

5.守护线程

from threading import Thread
import time


def sayhi(name):
    time.sleep(2)
    print('%s say hello' % name)


if __name__ == '__main__':
    t = Thread(target=sayhi, args=('nick',))
    t.setDaemon(True)  # 必须在t.start()之前设置
    t.start()

    print('主线程')
    print(t.is_alive())
    '''
    主线程
    True
    '''

6.互斥锁(同步锁)

from threading import Thread,Lock
import time

def task(lock):

    global n
    lock.acquire() #加锁
    temp = n
    time.sleep(1)
    n = temp - 1
    # n -= 1
    lock.release() #解锁


if __name__ == '__main__':
    n = 10
    l = []
    lock = Lock()
    for i in range(10):
        t = Thread(target=task, args=(lock, ) )
        t.start()
        l.append(t)

    for j in l:
        j.join()

    print(n)

7.信号量

from threading import Thread, Semaphore
from multiprocessing import Process, Lock
# Semaphore:信号量可以理解为多把锁,同时允许多个线程来更改数据

import time, random

sm = Semaphore(2)


def task(i):
    sm.acquire()
    print("线程:%s,进来了" % i)
    time.sleep(random.randint(1, 3))
    print("线程:%s,出去了" % i)
    sm.release()


if __name__ == '__main__':
    for i in range(6):
        t = Thread(target=task, args=(i,))
        t.start()

8.Event事件

一些线程需要等到其他线程执行完成之后才能执行,类似于发射信号

比如一个线程等待另一个线程执行结束再继续执行

from threading import Thread,Event
import time
event=Event()
def girl(name):
    print('%s 还在谈着恋爱'%name)
    time.sleep(3)
    event.set()
    print('%s 单身了'%name)


def boy(name):
    print('%s 等着女神分手'%name)
    event.wait()
    print('女神分手了,%s开始追'%name)

if __name__ == '__main__':
    t=Thread(target=girl,args=('刘亦菲',))
    t.start()
    for i in range(5):
        t=Thread(target=boy,args=('屌丝男%s号'%i,))
        t.start()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值