多线程
#在函数中执行线程.start_new_thread()
import _thread
import time
def go():
for i in range(5):
print(i,"---------------------")
time.sleep(1)
for i in range(5): #同时执行5次
_thread.start_new_thread(go,())
for j in range(6):
time.sleep(1)
print(“over”)
运行结果:
0 ---------------------
0 ---------------------
0 ---------------------
0 ---------------------
0 ---------------------
1 ---------------------
1 ---------------------
1 ---------------------
1 ---------------------
1 ---------------------
2 ---------------------
2 ---------------------
2 ---------------------
2 ---------------------
2 ---------------------
3 ---------------------
3 ---------------------
3 ---------------------
3 ---------------------
3 ---------------------
4 ---------------------
主进程与小弟进程:
import win32api
import _thread
def show(i):
mystr = win32api.MessageBox(0,“你真美”,“来自宁宁的问候”,0)
for i in range(5):
_thread.start_new_thread(show,(i,))
while True: # 在这里加入死循环是为了脚本主线程不死,小弟线程才能运行
pass
运行结果:
在这里插入代码片
1
线程冲突:
import _thread
NUM = 0
def A():
global NUM
for _ in range(100000):
NUM += 1
print(NUM)
for i in range(5):
_thread.start_new_thread(A,()) # 这里就是线程冲突,5个线程同时抢夺NUM的资源,导致最后结果错误
while True: # 防止主线程不死
pass
运行结果:
160129
128639
100000
260129
159767
import threading
import win32api
class Mythread(threading.Thread): # 继承threading.Thread类
def run(self): # 重写threading.Thread类中的run函数
win32api.MessageBox(0,“hello”,‘joker’,0)
for i in range(5): # 同时创建5个线程
t = Mythread() # 初始化
t.start() # 开启
while True:
pass
运行结果:
import threading
class yy(threading.Thread): #继承threading.Thread类
def init(self):
threading.Thread.init(self)
self.num = 0
def run(self):
for _ in range(1000):
self.num += 1
print(self.num) #每个num都被重写
if name == “main”:
for i in range(5):
t = yy()
t.start()
while 1:
pass
运行结果:
1000
1000
1000
1000
1000
线程阻塞:
import threading
class yy(threading.Thread): #继承threading.Thread类
def init(self):
threading.Thread.init(self)
self.num = 0
def run(self):
for _ in range(1000):
self.num += 1
print(self.num) #每个num都被重写
if name == “main”:
ts = []
for i in range(5):
t = yy()
t.start()
ts.append(t)
for t in ts:
t.join() #线程阻塞
print('Over')
运行结果:
1000
1000
1000
1000
1000
Over
无序线程:
import threading
class yy(threading.Thread): #继承threading.Thread类
def init(self,i):
threading.Thread.init(self)
self.num = 0
self.i = i
def run(self): #run函数中不要传参
print("&&*",i)
for _ in range(1000):
self.num += 1
print(self.num)
if name == “main”:
ts = []
for i in range(5):
t = yy(i)
t.start()
ts.append(t)
for t in ts:
t.join() #线程阻塞
print('Over')
运行结果:
&&* 0
1000
&&* 1
&&* 2 #线程之间是抢夺资源的
1000
1000
&&* 3
1000
&&* 4
1000
Over
基于类解决线程冲突
import threading
num = 0
mutex = threading.Lock() # 创建一个锁,threading.Lock()是一个类
class Myhtread(threading.Thread):
def run(self):
global num
if mutex.acquire(1): # 如果锁成功,那么线程继续干活,如果锁失败,下面的线程一直等待锁成功,1,代表独占
for i in range(1000): # 数字小的时候还是不会产生线程冲突的
num += 1
mutex.release() # 释放锁,一定切记
print(num)
mythread = []
for i in range(5):
t = Myhtread()
t.start()
mythread.append(t)
for thread in mythread:
thread.join() # 或者直接将thread.join()加入for i in range(5),也能解决线程冲突,但是貌似就变成单线程了
print(“game over”)
运行结果:
1000
2000
3000
4000
5000
game over
利用多线程随机找出100个验证码并存入本地
import threading
import random
class Myhtread(threading.Thread):
def init(self,lock):
threading.Thread.init(self)
self.lock = lock
self.list_ = []
def run(self):
for i in range(50):
x = random.randint(1000,9999)
print(x)
self.list_.append(x)
with self.lock: #用with可自动释放锁
self.write(self.list_)
def write(self,num):
b = [str(x)+'\n' for x in num]
b = ' '.join(b)
with open('E:/python/Homework6/res.txt',mode='a') as f:
f.write(b)
if name == “main”:
lock = threading.Lock()
ts = []
for i in range(2):
t = Myhtread(lock)
t.start()
ts.append(t)
for t in ts:
t.join()
print(“game over”)
死锁:
import threading
import time
boymutex = threading.Lock() # 创建一个锁
girlmutex = threading.Lock() # 创建一个锁
class boy(threading.Thread):
def run(self):
if boymutex.acquire(1): # 锁定成功就继续执行,锁定不成功,就一直等待
print(self.name + “boy say i am sorry up”)
# time.sleep(3) # 时间过短的话也可以并发执行,不会锁死
if girlmutex.acquire(1): # 锁定不成功,因为下面已经锁定
print(self.name + "boy say i am sorry down")
girlmutex.release()
boymutex.release()
class girl(threading.Thread):
def run(self):
if girlmutex.acquire(1): # 锁定成功就继续执行,锁定不成功,就一直等待
print(self.name + “girl say i am sorry up”)
# time.sleep(3)
if boymutex.acquire(1): # 锁定不成功,同理上面已经锁定一直等待
print(self.name + "girl say i am sorry down")
boymutex.release()
girlmutex.release()
for i in range(1000):
boy().start()
girl().start()
for i in range(1000):
boy().start()
girl().start()
运行结果:
Thread-1boy say i am sorry up
Thread-1boy say i am sorry down
Thread-2girl say i am sorry up
Thread-2girl say i am sorry down
Thread-3boy say i am sorry up
Thread-3boy say i am sorry down
Thread-4girl say i am sorry up
Thread-4girl say i am sorry down
Thread-5boy say i am sorry up
Thread-5boy say i am sorry down
Thread-6girl say i am sorry up
Thread-6girl say i am sorry down
Thread-7boy say i am sorry up
Thread-7boy say i am sorry down
Thread-8girl say i am sorry up
Thread-8girl say i am sorry down
Thread-9boy say i am sorry up
Thread-9boy say i am sorry down
Thread-10girl say i am sorry up
Thread-10girl say i am sorry down
Thread-11boy say i am sorry up
Thread-11boy say i am sorry down
Thread-12girl say i am sorry up
Thread-12girl say i am sorry down
Thread-13boy say i am sorry up
Thread-13boy say i am sorry down
Thread-14girl say i am sorry up
Thread-14girl say i am sorry down
Thread-15boy say i am sorry up
Thread-15boy say i am sorry down
Thread-16girl say i am sorry up
Thread-16girl say i am sorry down
Thread-17boy say i am sorry up
Thread-17boy say i am sorry down
Thread-18girl say i am sorry up
Thread-18girl say i am sorry down
Thread-19boy say i am sorry up
Thread-19boy say i am sorry down
Thread-20girl say i am sorry up
Thread-20girl say i am sorry down
Thread-21boy say i am sorry up
Thread-21boy say i am sorry down
Thread-22girl say i am sorry up
Thread-22girl say i am sorry down
Thread-23boy say i am sorry up
Thread-23boy say i am sorry down
Thread-24girl say i am sorry up
Thread-24girl say i am sorry down
Thread-25boy say i am sorry up
Thread-25boy say i am sorry down
Thread-26girl say i am sorry up
Thread-26girl say i am sorry down
Thread-27boy say i am sorry up
Thread-27boy say i am sorry down
Thread-28girl say i am sorry up
Thread-28girl say i am sorry down
Thread-29boy say i am sorry up
Thread-29boy say i am sorry down
Thread-30girl say i am sorry up
Thread-30girl say i am sorry down
Thread-31boy say i am sorry up
Thread-31boy say i am sorry down
Thread-32girl say i am sorry up
Thread-32girl say i am sorry down
Thread-33boy say i am sorry up
Thread-33boy say i am sorry down
Thread-34girl say i am sorry up
Thread-34girl say i am sorry down
Thread-35boy say i am sorry up
Thread-35boy say i am sorry down
Thread-36girl say i am sorry up
Thread-36girl say i am sorry down
Thread-37boy say i am sorry up
Thread-37boy say i am sorry down
Thread-38girl say i am sorry up
Thread-38girl say i am sorry down
Thread-39boy say i am sorry up
Thread-39boy say i am sorry down
Thread-40girl say i am sorry up
Thread-40girl say i am sorry down
Thread-41boy say i am sorry up
Thread-41boy say i am sorry down
Thread-42girl say i am sorry up
Thread-42girl say i am sorry down
Thread-43boy say i am sorry up
Thread-43boy say i am sorry down
Thread-44girl say i am sorry up
Thread-44girl say i am sorry down
Thread-45boy say i am sorry up
Thread-45boy say i am sorry down
Thread-46girl say i am sorry up
Thread-46girl say i am sorry down
Thread-47boy say i am sorry up
Thread-47boy say i am sorry down
Thread-48girl say i am sorry up
Thread-48girl say i am sorry down
Thread-49boy say i am sorry up
Thread-49boy say i am sorry down
Thread-50girl say i am sorry up
Thread-50girl say i am sorry down
Thread-51boy say i am sorry up
Thread-51boy say i am sorry down
Thread-52girl say i am sorry up
Thread-52girl say i am sorry down
Thread-53boy say i am sorry up
Thread-53boy say i am sorry down
Thread-54girl say i am sorry up
Thread-54girl say i am sorry down
Thread-55boy say i am sorry up
Thread-55boy say i am sorry down
Thread-56girl say i am sorry up
Thread-56girl say i am sorry down
Thread-57boy say i am sorry up
Thread-57boy say i am sorry down
Thread-58girl say i am sorry up
Thread-59boy say i am sorry up
RLock:
import threading
num = 0
mutext = threading.RLock() # PLOCK避免单线程死锁
class Mythreading(threading.Thread):
def run(self):
global num
if mutext.acquire(1):
num += 1
print(self.name, num)
if mutext.acquire(1):
num += 1000
mutext.release()
mutext.release()
for i in range(5): # 开启5个进程
t = Mythreading()
t.start()
运行结果:
Thread-1 1
Thread-2 1002
Thread-3 2003
Thread-4 3004
Thread-5 4005
线程通信:
import threading
import time
def goevent():
e = threading.Event() # 事件
def go():
e.wait() # 等待事件,线程卡顿,等待set消息
print("go")
threading.Thread(target=go).start() # 需要创建一个线程
return e
t = goevent()
time.sleep(3)
t.set() # 激发事件
运行结果:go
import threading
import time
def deco2(times):
def deco(func):
def warp(*args,**kwargs):
e = args[0]
time.sleep(times)
e.set()
return func(*args,**kwargs)
return warp
return deco
@deco2(5)
def A(e):
e.wait()
print(‘hello world!’)
if name==“main”:
e = threading.Event()
t = threading.Thread(target=A,args=(e,))
t.start()
t.join()
运行结果: 5秒后输出hello world!
利用多线程爬取十个网页中电影名及其评分,并存在本地
import requests
import threading
import re
class maoyan_top500(threading.Thread):
def init(self, start_, end_,lock):
threading.Thread.init(self)
self.headers = {
‘User-Agent’:
‘Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36’
}
self.base_url = ‘https://maoyan.com/board/4?offset=%d’
self.start_ = start_
self.end_ = end_
self.lock = lock
def run(self):
for offset in range(self.start_, self.end_, 10):
url = self.base_url % offset
response = requests.get(url, headers=self.headers)
html = response.text
info_list = self.get_Information(html)
with self.lock:
self.write(info_list)
print('offset {} OK !'.format(offset))
def get_Information(self, html):
information_list = []
for line in html.split('\n'):
if 'class="image-link"' in line:
movie_name = line.split('title="')[1].split('"')[0]
information_list.append(movie_name)
if 'class="integer"' in line:
res = re.search(
'<p class="score"><i class="integer">(\d\.)</i><i class="fraction">(\d)</i></p>',
line)
integer = res.group(1)
fraction = res.group(2)
score = integer + fraction
information_list.append(score)
return information_list
def write(self,info_list):
str_ = str(info_list) + '\n'
with open('E:/python/Homework05/novel/res.txt',mode='a',encoding='utf8') as file:
file.write(str_)
if name == “main”:
threads = []
lock = threading.Lock()
for i in range(2):
t = maoyan_top500(start_=i * 50, end_=(i + 1) * 50,lock=lock)
t.start()
threads.append(t)
for t in threads:
t.join()
print('Over')