2.进程:程序运行的过程。
进程——线程的区别:
4.进程用来分配空间(从来分配资源),线程用来执行操作
5.在一个进程内的所有线程共享全局变量, 多线程之间的数据共享(这点要比多进程要好)
缺点就是, 可能造成多个线程同时修改一个变量(即线程非安全),可能造成混乱
import threading
if __name__ == "__main__":
#任何进程默认会启动一个线程,这个线程称为主线程,主线程可以启动新的子线程
#current_thread():返回当前线程的实例
#.name :当前线程的名称
print(‘主线程%s启动‘ %(threading.current_thread().name))
import threading,time
def saySorry():
print("子线程%s启动" %(threading.current_thread().name))
time.sleep(1)
print("亲爱的,我错了,我能吃饭了吗?")
if __name__ == "__main__":
print(‘主线程%s启动‘ %(threading.current_thread().name))
for i in range(5):
t = threading.Thread(target=saySorry))#Thread():指定线程要执行的代码
t.start()
import threading
import time
def sing():
for i in range(3):
print("正在唱歌...%d" %i)
time.sleep(1)
def dance():
for i in range(2):
print("正在跳舞...%d" %i)
time.sleep(1)
if __name__ == "__main__":
print("开始:%s" %time.time())
t1 = threading.Thread(target=sing)
t2 = threading.Thread(target=dance)
t1.start()
t2.start()
while True:
length = len(threading.enumerate())
#threading.enumerate():返回当前运行中的Thread对象列表
print("当前线程数为:%d" %length)
if length<=1:
break
time.sleep(1)
第一:通过 threading.Thread 直接在线程中运行函数;
第二:通过继承 threading.Thread 类来创建线程
这种方法只需要重载 threading.Thread 类的 run 方法,然后调用 start()开启线程就可以了
import threading
class MyThread(threading.Thread):
def run(self):
for i in range(5):
print(i)
if __name__ == "__main__":
t1 = MyThread()
t2 = MyThread()
t1.start()
t2.start()
import threading
import time
class MyThread(threading.Thread):
def run(self):
for i in range(3):
time.sleep(1)
msq = "I`m" + self.name + "@" + str(i)
#name属性中保存了当前线程的名字
print(msq)
if __name__ == "__main__":
t = MyThread()
t.start()
1.新状态:线程对象已经创建,还没有在其上调用start()方法。
import threading
import time
num = 100
def work1():
global num
for i in range(3):
num += 1
print("---in work1,num is %d" %num)
def work2():
global num
print("---in work2,num is %d" %num)
print("---线程创建之前 num is %d" %num)
t1 = threading.Thread(target=work1)
t1.start()
time.sleep(1)
#延时一会保证线程1中的任务做完
t2 = threading.Thread(target=work2)
t2.start()
import threading,time
def work1(nums):
nums.append(44)
print(‘-----in work1-----‘ ,nums)
def work2(nums):
time.sleep(1)
#延时一会保证另一线程执行
print(‘-----in work2-----‘, nums)
g_nums = [11,22,33]
t1 = threading.Thread(target=work1,args=(g_nums,))
t1.start()
t2 = threading.Thread(target=work2,args=(g_nums,))
t2.start()
import threading
num = 0
def test1():
global num
for i in range(100):#一百万错误
num += 1
def test2():
global num
for i in range(100):#一百万错误
num += 1
p1 = threading.Thread(target=test1)
p1.start()
p2 = threading.Thread(target=test2)
p2.start()
print("---num = %d---" %num)
创建锁mutex = threading.Lock()
锁定mutex.acquire()
释放mutex.release() #解锁
import threading
num = 0
def test1():
global num
if mutex.acquire():
for i in range(1000):
num += 1
mutex.release()
def test2():
global num
if mutex.acquire():
for i in range(1000):
num += 1
mutex.release()
mutex = threading.Lock()
p1 = threading.Thread(target=test1)
p1.start()
p2 = threading.Thread(target=test2)
p2.start()
print(num)
死锁(错误情况,理解即可)在线程间共享多个资源的时候, 如果两个线程分别占有一部分资源并且同时等待对方的资源, 就会造成死锁
import threading
import time
class MyThread1(threading.Thread):
def run(self):
if mutexA.acquire():
print(self.name + ‘---do1---up---‘)
time.sleep(1)
if mutexB.acquire():
print(self.name + ‘---do1---down---‘)
mutexB.release()
mutexA.release()
class MyThread2(threading.Thread):
def run(self):
time.sleep(1)
if mutexB.acquire():
print(self.name + ‘---do2---up---‘)
if mutexA.acquire():
print(self.name + ‘---do2---down---‘)
mutexA.release()
mutexB.release()
if __name__ == ‘__main__‘:
mutexA = threading.Lock()
mutexB = threading.Lock()
t1 = MyThread1()
t2 = MyThread2()
t1.start()
t2.start()
import time
import threading
def foo():
time.sleep(2)
print("ok",time.ctime())
for i in range(100):
t1=threading.Thread(target=foo)
t1.start() #此时无法控制同时进入的线程数
import time
import threading
s1=threading.Semaphore(5) (赛么佛)
def foo():
s1.acquire()
time.sleep(2)
print("ok")
s1.release()
for i in range(20):
t1=threading.Thread(target=foo,args=())
t1.start() #此时可以控制同时进入的线程数
解释器分为,Cpython,Jpython,Pypy
为什么这么干,因为当时写python的时候,只有一个CPU,没有多核CPU
为什么不取消:
同步调用:确定调用的顺序
提交一个任务,自任务开始运行直到此任务结束,我再提交下一个任务
按顺序购买四大名著
异步调用:不确定顺序
一次提交多个任务,然后我就直接执行下一行代码
你喊你朋友吃饭 ,你朋友说知道了 , 待会忙完去找你 ,你就去做别的了
给三个老师发布任务:
同步: 先告知第一个老师完成写书的任务,我原地等待,等他两个月之后完成了,我再发布下一个任务......
异步:直接将三个任务告知三个老师,我就忙我的我,直到三个老师完成之后,告知我
同步意味着顺序、统一的时间轴
import threading,time
class Task1(threading.Thread):
def run(self):
while True:
if lock1.acquire():
print(‘-----Task1-----‘)
time.sleep(1)
lock2.release()
class Task2(threading.Thread):
def run(self):
while True:
if lock2.acquire():
print(‘-----Task2-----‘)
time.sleep(1)
lock3.release()
class Task3(threading.Thread):
def run(self):
while True:
if lock3.acquire():
print(‘-----Task3-----‘)
time.sleep(1)
lock1.release()
lock1 = threading.Lock()
#创建另外一把锁,并且锁上
lock2 = threading.Lock()
lock2.acquire()
#再创建一把锁并锁上
lock3 = threading.Lock()
lock3.acquire()
t1 = Task1()
t2 = Task2()
t3 = Task3()
t1.start() t2.start() t3.start()
Python的Queue模块:实现了3种类型的队列来实现线程同步,包括:
FIFO(先进先出) 队列 Queue,
LIFO(后进先出) 栈 LifoQueue,
优先级队列 PriorityQueue
区别在于队列中条目检索的顺序不同
在FIFO队列中,按照先进先出的顺序检索条目
在LIFO队列中,最后添加的条目最先检索到(操作类似一个栈)
在优先级队列中,条目被保存为有序的(使用heapq模块)并且最小值的条目被最先检索
这些队列都实现了锁原语(可以理解为原?操作, 即要么不做, 要么就做完) , 能够在多线程中直接使用
现阶段只要求掌握其中一种,FIFO队列
import threading
import time
from queue import Queue
class Pro(threading.Thread):
def run(self):
global queue
count = 0
while True:
if queue.qsize()<1000:
for i in range(100):
count = count + 1
msg = ‘生成产品‘ + str(count)
queue.put(msg)#队列中添加新产品
print(msg)
time.sleep(1)
class Con(threading.Thread):
def run(self):
global queue
while True:
if queue.qsize() > 100:
for i in range(3):
msg = self.name + ‘消费了‘ + queue.get()
print(msg)
time.sleep(1)
if __name__ == "__main__":
queue = Queue()
#创建一个队列。线程中能用,进程中不能使用
for i in range(500):#创建500个产品放到队列里
queue.put(‘初始产品’ + str(i))#字符串放进队列
for i in range(2):#创建了两个线程
p = Pro()
p.start()
for i in range(5):#5个线程
c = Con()
c.start()
import threading, time
def thead(num):
print("线程%s开始执行" % num)
time.sleep(3)
print("线程%s执行完毕" % num)
print("主方法开始执行")
poll = []
for i in range(1, 3):
thead_one = threading.Thread(target=thead, args=(i,))
poll.append(thead_one)
for n in poll:
n.start() # 准备就绪,等待cpu执行
print("主方法执行完毕")
import threading,time
num = 0
def test1():
global num
while True:
if mutex.acquire(False):
for i in range(1000000):
num += 1
print("1", num)
mutex.release()
break
else:
print("该干嘛干嘛")
def test2():
global num
while True:
if mutex.acquire(False):
for i in range(1000000):
num += 1
print("2", num)
mutex.release()
break
else:
print("该干嘛干嘛")
mutex = threading.Lock()
p1 = threading.Thread(target=test1)
p2 = threading.Thread(target=test2)
p1.start()
p2.start()
from multiprocessing import Pool
import random
import time
def download(f):
for i in range(1,4):
print(f"{f}下载文件{i}")
time.sleep(random.randint(1,3))
return "下载完成"
def alterUser(msg):
print(msg)
if __name__ == "__main__":
p = Pool(3)
# 当func执行完毕后,return的东西会给到回调函数callback
p.apply_async(func= download,args=("线程1",),callback = alterUser)
p.apply_async(func=download, args=("线程2",),callback =alterUser)
p.apply_async(func=download, args=("线程3",),callback =alterUser)
p.close()
p.join()
原文:https://www.cnblogs.com/huoxc/p/13304396.html