开启线程的第一种方式:
from threading import Thread
from multiprocessing import Process
def task():
print("threading running!")
t1 = Thread(target=task)
t1.start()
print("over")
#threading running!
#over
开启线程的第二中方式:
from threading import Thread
from multiprocessing import Process
class MyThread(Thread):
def run(self):
print("子线程 running....")
MyThread().start()
print("over2")
100个进程时间统计:
from multiprocessing import Process
import time
def task():
pass
# 100个进程时间统计
if __name__ == '__main__':
start = time.time()
ps = []
for i in range(100):
p = Process(target=task)
p.start()
ps.append(p)
for p in ps:
p.join()
print(time.time()-start) #时间为6.289931774139404
100个线程时间统计:
from threading import Thread
import time
def task():
pass
start = time.time()
ts = []
for i in range(100):
t = Thread(target=task)
t.start()
ts.append(t)
for t in ts:
t.join()
print(time.time()-start) #0.013973474502563477
from threading import Thread
x = 100
def task():
print('run....')
global x
x = 0
t = Thread(target=task)
t.start()
t.join()
print(x)
print('over')
#run....
#0
#over
from threading import Thread
import time
def task():
print('子线程运行')
time.sleep(1)
print('子线程结束')
t = Thread(target=task)
t.setDaemon(True)
t.start()
print("over")
#子线程运行
#over
from threading import Thread,current_thread,enumerate,active_count
import os
def task():
print('running...')
print(os.getpid()) #获取线程pid
print(current_thread()) #获取当前线程对象
print(active_count()) #获取当前正在运行的线程个数,包括主线程
t1 = Thread(target=task)
t1.start()
print(t1.is_alive()) #线程是否存活
print(t1.isAlive()) #线程是否存活
print(t1.getName()) #线程的名字
#获取所有线程对象列表
print(enumerate()) #[<_MainThread(MainThread, started 47944)>, ]
import time
from threading import Thread,Lock
lock =Lock()
a = 100
def task():
lock.acquire()
global a
temp = a - 1
time.sleep(0.01)
a = temp
lock.release()
ts = []
for i in range(100):
t = Thread(target=task)
t.start()
ts.append(t)
for t in ts:
t.join()
print(a) #0
from threading import Semaphore,Thread,current_thread
import time,random
sem = Semaphore(3)
def task():
sem.acquire()
print("%s run..." % current_thread())
time.sleep(3)
sem.release()
for i in range(10):
t = Thread(target=task)
t.start()
生成者与消费者模型
import time, random
from multiprocessing import Process, JoinableQueue
def eat_hotdog(name, q):
while True:
res = q.get()
print('%s吃了%s' % (name, res))
time.sleep(random.randint(1, 2))
q.task_done()
def make_hotdog(name, q):
for i in range(1, 6):
time.sleep(random.randint(1, 2))
print("%s生产了第%s个热狗" % (name, i))
res = "%s的%s个热狗" % (name, i)
q.put(res)
if __name__ == '__main__':
q = JoinableQueue()
#生产者1
c1 = Process(target=make_hotdog, args=('万达热狗店', q))
c1.start()
#生产者2
c2 = Process(target=make_hotdog, args=('老男孩狗店', q))
c2.start()
#消费者
p2 = Process(target=eat_hotdog, args=('思聪', q))
p2.daemon = True
p2.start()
#首先保证生产者全部产完成
c1.join()
c2.join()
#保证队列中的数据全部被处理了
q.join() #明确生产方已经不会再生成数据了
练习:
"""
1.基于多线程+TCP协议实现上传下载功能
多个人可以同时上传和下载,如果一个客户端相应同时并发的上传或下载多个文件 则必须为每一个上传/下载任务,建立新的连接,不能共享同一个,会造成数据错乱
2.编写一个文本处理工具,总共三个任务,一个接收用户输入,一个将用户输入的内容格式化成大写,一个将格式化后的结果存入文件
"""
上传下载服务端:
from threading import Thread
from concurrent.futures import ThreadPoolExecutor
import socket,json,struct,os
import common
server = socket.socket()
server.bind(("127.0.0.1",8989))
server.listen()
pool = ThreadPoolExecutor()
def recv_file(c):
common.recv_file(c)
def send_file(c):
common.send_file(c,r"D:\Program Files\Python\zdc\day35\多线程服务端.py","aaa.txt")
def task(c):
print("执行了 task....")
while True:
# 接收用户数据 判断用户要执行的操作
try:
len_data = c.recv(4)
if not len_data:
c.close()
break
head_len = struct.unpack("i",len_data)[0]
head = json.loads(c.recv(head_len).decode("utf-8"))
print(head)
print("服务器 收到一个请求")
if head["func"] == "download":
print("send....")
pool.submit(send_file,c)
elif head["func"] == "upload":
recv_file(c)
else:
print("客户端请求错误!..")
except ConnectionResetError:
c.close()
break
while True:
client,addr = server.accept()
pool.submit(task,client)
上传下载客户端:
import socket,json,struct,os
import common
from threading import Thread
is_uploading = False
is_downloading = False
c = socket.socket()
c.connect(("127.0.0.1",8989))
def download():
global is_downloading
if is_downloading:
print("您有一个任务正在下载.....")
return
is_downloading = True
print("11111")
head = {"func":"download"}
head_data = json.dumps(head).encode("utf-8")
c.send(struct.pack("i",len(head_data)))
c.send(head_data)
common.recv_file(c)
is_downloading = False
def upload():
global is_uploading
if is_uploading:
print("您有一个任务正在上传.....")
return
is_uploading = True
head = {"func": "upload"}
head_data = json.dumps(head).encode("utf-8")
c.send(struct.pack("i", len(head_data)))
c.send(head_data)
common.send_file(c,r"D:\Program Files\Python\zdc\day35\多线程客户端.py","nb.txt")
is_uploading = False
funcs = {"1":download,"2":upload}
while True:
res = input("请输入 1:下载 2:上传 q:退出").strip()
if res == "q":
break
if res not in funcs:
print("输入有误!")
continue
Thread(target=funcs[res]).start()# 开启线程执行上传或下载
==========================common.py==========================
import os,json,struct
import time
def send_file(c,filepath,filename):
print("发送数据")
f = open(filepath, "rb")
file_info = {"name": filename, "size": os.path.getsize(filepath)}
head_data = json.dumps(file_info).encode("utf-8")
c.send(struct.pack("i", len(head_data)))
c.send(head_data)
time.sleep(5)
# 发送文件
while True:
data = f.read(1024)
if not data:
break
c.send(data)
print("发送完成!")
f.close()
def recv_file(c):
print("接收数据")
# 接收数据
len_data = c.recv(4)
head_len = struct.unpack("i", len_data)[0]
file_info = json.loads(c.recv(head_len).decode("utf-8"))
size = file_info["size"]
recv_size = 0
f = open(file_info["name"], "wb")
while recv_size < size:
data = c.recv(1024)
f.write(data)
recv_size += len(data)
f.close()
print("接收完成")
第二题:
from threading import Thread
import time
ls = []
up_ls = []
def input_data():
while True:
data = input(">>>:")
ls.append(data)
def upper_data():
while True:
if ls:
data = ls.pop(0).upper()
up_ls.append(data)
time.sleep(0.1)
def write_data():
with open("test.txt","wt",encoding="utf-8") as f:
while True:
if up_ls:
f.write(up_ls.pop(0))
f.flush() # 立即将数据刷到硬盘
time.sleep(0.1)
Thread(target=input_data).start()
Thread(target=upper_data).start()
Thread(target=write_data).start()
==========================================================
第二种方法:
from threading import Thread
from queue import Queue
def get_input(p):
while True:
msg = input(">>>").strip()
p.put(msg)
if msg == 'exit':break
def upper_msg(p,p2):
while True:
msg = p.get()
new_msg = msg.upper()
p2.put(new_msg)
if msg == 'exit':break
def write_file(p2):
while True:
msg = p2.get()
if msg == 'EXIT':break
with open('test.txt','at',encoding='utf-8') as f:
f.write(msg)
print('done')
if __name__ == '__main__':
q = Queue()
q2 = Queue()
t1 = Thread(target=get_input,args=(q,))
t2 = Thread(target=upper_msg,args=(q,q2))
t3 = Thread(target=write_file,args=(q2,))
t1.start()
t2.start()
t3.start()