线程的概念&与进程的区别?
进程是计算机分配资源的最小单位
线程是计算机中可以被cpu调度的最小单位
一个进程中可以有多个线程,同一个进程中的线程可以共享此进程中的资源,一个进程中至少有一个线程(一个应用程序中至少有一个进程)
?
在python中因为有GIL锁,同一时刻保证一个进程中只有一个线程可以被cpu调度,所以在使用python开发时要注意:
计算密集型,用多进程
IO密集型,用多线程
默认进程之间不能进行资源共享,如果非要进行通信,可以基于:文件/网络/Queue
多线程的应用
快速应用
import threading
def task(arg):
pass
t = threading.Thread(target=task,args=(1,)) # 实例化一个线程
t.start() # 将线程提交给cpu 什么时候被调度看cpu
import threading
def task(arg):
ret = requests.get(arg)
file_name = arg.rsplit(‘/‘, maxsplit=1)[-1]
with open(file_name, mode=‘wb‘) as f:
f.write(ret.content)
for url in url_list:
# 实例化一个线程对象
t = threading.Thread(target=task,args=(url,))
# 将线程提交给cpu
t.start()
常见的方法
t.start() 将线程提交给cpu,由cpu来进行调度
t.join() 等待
import threading
?
?
# 示例1
"""
loop = 10000000
number = 0
?
def _add(count):
global number
for i in range(count):
number += 1
?
?
t = threading.Thread(target=_add,args=(loop,))
t.start()
?
t.join()
print(number)
"""
?
# 示例2
"""
loop = 10000000
number = 0
?
def _add(count):
global number
for i in range(count):
number += 1
?
def _sub(count):
global number
for i in range(count):
number -= 1
?
t1 = threading.Thread(target=_add,args=(loop,))
t2 = threading.Thread(target=_sub,args=(loop,))
t1.start()
t2.start()
?
print(number)
"""
?
?
# 示例3
"""
loop = 10000000
number = 0
?
def _add(count):
global number
for i in range(count):
number += 1
?
def _sub(count):
global number
for i in range(count):
number -= 1
?
t1 = threading.Thread(target=_add,args=(loop,))
t2 = threading.Thread(target=_sub,args=(loop,))
t1.start()
t2.start()
t1.join() # t1线程执行完毕,才继续往后走
t2.join() # t2线程执行完毕,才继续往后走
?
print(number)
"""
?
# 示例4
"""
loop = 10000000
number = 0
?
def _add(count):
global number
for i in range(count):
number += 1
?
def _sub(count):
global number
for i in range(count):
number -= 1
?
t1 = threading.Thread(target=_add,args=(loop,))
t2 = threading.Thread(target=_sub,args=(loop,))
t1.start()
t1.join() # t1线程执行完毕,才继续往后走
t2.start()
t2.join() # t2线程执行完毕,才继续往后走
?
print(number)
"""
t.setDaemon() 设置称为守护线程
import threading
import time
def task(arg):
time.sleep(5)
print(‘任务‘)
t = threading.Thread(target=task,args=(11,))
t.setDaemon(True)
t.start()
print(‘END‘)
线程名称的设置和获取
import threading
def task(arg):
# 获取当前执行此代码的线程
name = threading.current_thread().getName()
print(name)
for i in range(10):
t = threading.Thread(target=task,args=(11,))
t.setName(‘日魔-%s‘ %i )
t.start()
run() 自定义线程时,cpu调度执行的方法
class RiMo(threading.Thread):
def run(self):
print(‘执行此线程‘,self._args)
?
obj = RiMo(args=(100,))
obj.start()
练习题:基于socket和多线程实现类似与socketserver模块的功能
import socket
import threading
?
?
def task(connect,address):
pass
?
?
server = socket.socket()
server.bind((‘127.0.0.1‘,9000))
server.listen(5)
while True:
conn,addr = server.accept()
# 处理用户请求
t = threading.Thread(target=task,args=(conn,addr,))
t.start()
多线程安全
多个线程同时去操作一个‘东西’,不要存在数据混乱
线程安全:logging模块/列表
线程不安全:自己做文件操作/同时修改一个数字
使用锁来保证数据安全,来了多个线程,使用锁让他们排队,逐一执行
Lock
import threading
import time
num = 0
# 线程锁
lock = threading.Lock()
def task():
global num
# # 申请锁
# lock.acquire()
# num += 1
# time.sleep(0.2)
# print(num)
# # 释放锁
# lock.release()
with lock:
num += 1
time.sleep(0.2)
print(num)
for i in range(10):
t = threading.Thread(target=task)
t.start()
RLock
import threading
import time
num = 0
# 线程锁
lock = threading.RLock()
def task():
global num
# 申请锁
lock.acquire()
num += 1
lock.acquire()
time.sleep(0.2)
print(num)
# 释放锁
lock.release()
lock.release()
for i in range(10):
t = threading.Thread(target=task)
t.start()
练习题:基于线程锁完成一个单例模式
import threading
import time
class Singleton:
instance = None
lock = threading.RLock()
def __init__(self, name):
self.name = name
def __new__(cls, *args, **kwargs):
if cls.instance:
return cls.instance
with cls.lock:
if cls.instance:
return cls.instance
time.sleep(0.1)
cls.instance = object.__new__(cls)
return cls.instance
def task():
obj = Singleton(‘x‘)
print(obj)
for i in range(10):
t = threading.Thread(target=task)
t.start()
?
# 执行1000行代码
data = Singleton(‘asdfasdf‘)
print(data)
GIL 全局解释器锁
同一时刻保证一个进程中只有一个线程可以被cpu调度,所以在使用Python开发时要注意:
计算密集型,用多进程.
IO密集型,用多线程.
python中如果创建多线程无法应用计算机的多核优势
原文:https://www.cnblogs.com/womenzt/p/12427995.html