标签:code 解决方法 not 子进程 run方法 回收 bar rand 结果
# 方式一 引用模块中Thread类方法
from threading import Thread
import time
def sayhi(name):
time.sleep(2)
print(f'{name} say hi')
if __name__ == '__main__':
t = Thread(target=sayhi, args=('麻花腾',))
t.start()
print('in 主线程')
-----------------------------------------------------------
# 方式二 自定义类,继承Thread类方法,重写run方法
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(f'{self.name} say hello')
if __name__ == '__main__':
t = Sayhi('孙悟空')
t.start()
print('in 主线程')
# 开启速度对比
from threading import Thread
from multiprocessing import Process
def sayhi(name):
print(f'{name} say hi')
if __name__ == '__main__':
t = Thread(target=sayhi, args=('孙悟空',))
p = Process(target=sayhi, args=('猪八戒',))
t.start()
p.start()
print('in 主进程/主线程')
# 孙悟空 say hi
# in 主进程/主线程
# 猪八戒 say hi
# 线程的开启速度比进程的开启速度快
# pid对比
from threading import Thread
from multiprocessing import Process
import os
def sayhi(name):
print(f'{name}{os.getpid()} say hi')
if __name__ == '__main__':
t = Thread(target=sayhi, args=('子线程',))
p = Process(target=sayhi, args=('子进程',))
t.start()
p.start()
print('in 主进程/主线程', os.getpid())
# 子线程12812 say hi
# in 主进程/主线程 12812
# 子进程12648 say hi
# 在主进程下开启多个线程,每个线程都跟主进程的pid一样
# 开多个进程,每个进程都有不同的pid
# 同一进程内的线程共享数据
from threading import Thread
from multiprocessing import Process
import os
def work():
global n
n = 0
if __name__ == '__main__':
# n = 100
# p = Process(target=work)
# p.start()
# p.join()
# print('主进程', n)
# 毫无疑问子进程p已经将自己的全局的n改成了0,但改的仅仅是它自己的,查看父进程的n仍然为100
n = 1
t = Thread(target=work)
t.start()
t.join()
print('主线程', n)
# 查看结果为0,因为同一进程内的线程之间共享进程内的数据
# socket小练习
# 多线程实现并发: server端
from threading import Thread
import socket
server = socket.socket()
server.bind(('127.0.0.1', 2019))
server.listen(5)
def action(conn):
while 1:
data = conn.recv(1024).decode('utf-8')
print(data)
conn.send(data.upper().encode('utf-8'))
if __name__ == '__main__':
while 1:
conn, addr = server.accept()
t = Thread(target=action, args=(conn,))
t.start()
----------------------------------------------------------
# client端
import socket
client = socket.socket()
client.connect(('127.0.0.1', 2019))
while 1:
t_s = input('>>>').strip()
if not t_s:
continue
client.send(t_s.encode('utf-8'))
f_s = client.recv(1024).decode('utf-8')
print(f_s)
from threading import Thread
import threading
import time
def sayhi(name):
time.sleep(2)
print(f'{name} say hi')
if __name__ == '__main__':
t = Thread(target=sayhi, args=('麻花腾',))
t.start()
# 线程对象的方法
print(t.is_alive()) # 判断子线程是否存活
print(t.getName()) # 返回线程名
t.setName('线程11') # 设置线程名
print(t.getName())
# threading模块的方法:
print(threading.current_thread().name) # 获取此线程对象,可以使用此对象
print(threading.enumerate()) # 返回一个列表,放置的是所有线程对象
print(threading.active_count()) # 获取活跃的线程个数,包括主线程
# 回顾守护进程
from multiprocessing import Process
import time
def foo():
print(123) # 开启进程太慢了,还没来得及打印,主进程就结束了
time.sleep(1)
print("end123")
def bar():
print(456)
time.sleep(3)
print("end456")
if __name__ == '__main__':
p1 = Process(target=foo)
p2 = Process(target=bar)
p1.daemon = True
p1.start()
p2.start()
print("main-------")
# main-------
# 456
# end456
# 守护线程
from threading import Thread
import time
def foo():
print(123)
time.sleep(1)
# 比非守护线程短,主线程等到所有非守护子线程结束才结束,此守护线程已经运行完毕
print("end123")
def bar():
print(456)
time.sleep(3)
print("end456")
if __name__ == '__main__':
t1 = Thread(target=foo)
t2 = Thread(target=bar)
t1.daemon = True
t1.start()
t2.start()
print("main-------")
# 123
# 456
# main-------
# end123
# end456
-----------------------------------------------------------
from threading import Thread
import time
def foo():
print(123)
time.sleep(4)
# 比非守护线程长,非守护线程结束时主线程也结束,此守护线程也同时结束,后面不会打印
print("end123")
def bar():
print(456)
time.sleep(3)
print("end456")
if __name__ == '__main__':
t1 = Thread(target=foo)
t2 = Thread(target=bar)
t1.daemon = True
t1.start()
t2.start()
print("main-------")
# 123
# 456
# main-------
# end456
# 多线程是同一个空间,同一个进程
# 主线程是进程空间存活在内存的必要条件
# 主线程会等所有非守护子线程结束才能结束
无论是进程还是线程,都遵循: 守护xx会等待主xx运行完毕后被销毁
需要强调的是: 运行完毕并非终止运行
对主进程来说,运行完毕指的是主进程代码运行完毕
主进程在其代码结束后就已经算运行完毕了(守护进程在此时就被回收),然后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(否则会产生僵尸进程),才会结束
对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕
主线程在其他非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收).因为主线程的结束意味着进程的结束,进程整体的资源都将被回收,而进程必须保证非守护线程都运行完毕后才能结束
from threading import Thread
import time
x = 100
def task():
global x
temp = x
time.sleep(1)
temp -= 1
x = temp
if __name__ == '__main__':
t1 = Thread(target=task)
t1.start()
t1.join()
print('主线程', x) # 99
------------------------------------------------------
from threading import Thread
import time
x = 100
def task():
global x
temp = x
time.sleep(1)
temp -= 1
x = temp
if __name__ == '__main__':
lst = []
for i in range(100):
t = Thread(target=task)
t.start()
lst.append(t)
for el in lst:
el.join()
print('主线程', x) # 99
# 因为100个子线程近乎同时运行,同时取得temp=100,又分别对x赋值99
from threading import Thread
from threading import Lock
import time
x = 100
def task(lock):
lock.acquire()
global x
temp = x
time.sleep(0.1)
temp -= 1
x = temp
lock.release()
if __name__ == '__main__':
lock = Lock()
lst = []
for i in range(100):
t = Thread(target=task, args=(lock,))
t.start()
lst.append(t)
for el in lst:
el.join()
print('主线程', x) # 0
# 互斥锁与join的区别
# 互斥锁随机抢锁,公平 join提前排好顺序,不公平 都是串行
# 死锁现象
from threading import Thread
from threading import Lock
import time
lock_A = Lock()
lock_B = Lock()
class Sayhi(Thread):
def run(self):
self.f1()
self.f2()
def f1(self):
lock_A.acquire()
print(f'{self.name}拿到A锁')
lock_B.acquire()
print(f'{self.name}拿到B锁')
lock_B.release()
lock_A.release()
def f2(self):
lock_B.acquire()
print(f'{self.name}拿到B锁')
time.sleep(1)
lock_A.acquire()
print(f'{self.name}拿到A锁')
lock_A.release()
lock_B.release()
if __name__ == '__main__':
t1 = Sayhi()
t1.start()
t2 = Sayhi()
t2.start()
t3 = Sayhi()
t3.start()
print('in 主线程')
# Thread-1拿到A锁
# Thread-1拿到B锁
# Thread-1拿到B锁
# Thread-2拿到A锁
# in 主线程
# 程序夯住了
# 递归锁是一把锁,锁上有counter变量,只要acquire一次,counter就加一,release一次,counter减一,只要counter不为0,其他线程不能抢
from threading import Thread
from threading import RLock
import time
lock_B = lock_A = RLock()
class Sayhi(Thread):
def run(self):
self.f1()
self.f2()
def f1(self):
lock_A.acquire()
print(f'{self.name}拿到A锁')
lock_B.acquire()
print(f'{self.name}拿到B锁')
lock_B.release()
lock_A.release()
def f2(self):
lock_B.acquire()
print(f'{self.name}拿到B锁')
time.sleep(1)
lock_A.acquire()
print(f'{self.name}拿到A锁')
lock_A.release()
lock_B.release()
if __name__ == '__main__':
t1 = Sayhi()
t1.start()
t2 = Sayhi()
t2.start()
t3 = Sayhi()
t3.start()
print('in 主线程')
# 实例: 同时只有5个线程可以获得semaphore,即可以限制最大连接数为5
from threading import Thread
from threading import Semaphore
from threading import current_thread
import time
import random
sem = Semaphore(5)
def go_public_wc():
sem.acquire()
print(f'{current_thread().getName()} 上厕所ing')
time.sleep(random.randint(1, 3))
sem.release()
if __name__ == '__main__':
for i in range(1, 21):
t = Thread(target=go_public_wc, name=f'{i}号')
t.start()
标签:code 解决方法 not 子进程 run方法 回收 bar rand 结果
原文地址:https://www.cnblogs.com/douzi-m/p/11241573.html