灵虚御风
醉饮千觞不知愁,忘川来生空余恨!

导航

 

TCP

import socket

client = socket.socket()
client.connect(('127.0.0.1',8080))
while True:
    client.send(b'hello')
    data = client.recv(1024)
    print(data.decode('utf-8'))
client.py
""""""
"""
服务端
    1.要有固定的IP和PORT
    2.24小时不间断提供服务
    3.能够支持并发
"""
import socket
from threading import Thread

server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)


def talk(conn):
    while True:
        try:
            data = conn.recv(1024)
            if len(data) == 0: break
            print(data.decode('utf-8'))
            conn.send(data.upper())
        except ConnectionResetError as e:
            print(e)
            break
    conn.close()


while True:
    conn, addr = server.accept()  # # 监听 等待客户端的连接  阻塞态
    print(addr)
    t = Thread(target=talk, args=(conn,))
    t.start()
server.py

 

""""""
"""
In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple
native threads from executing Python bytecodes at once. This lock is necessary mainly
because CPython’s memory management is not thread-safe.
"""
"""
ps:python解释器有很多种  最常见的就是Cpython解释器
GIL本质也是一把互斥锁:将并发变成串行牺牲效率保证数据的安全 
用来阻止同一个进程下的多个线程的同时执行(同一个进程内多个线程无法实现并行但是可以实现并发)
    python的多线程没法利用多核优势  是不是就是没有用了?
    
GIL的存在是因为CPython解释器的内存管理不是线程安全的

垃圾回收机制
    1.引用计数
    2.标记清除
    3.分代回收


研究python的多线程是否有用需要分情况讨论
四个任务 计算密集型的  10s
单核情况下
    开线程更省资源
多核情况下
    开进程 10s
    开线程 40s

四个任务 IO密集型的  
单核情况下
    开线程更节省资源
多核情况下
    开线程更节省资源

"""
"""计算密集型"""

from multiprocessing import Process
from threading import Thread
import os,time

def work():
    res = 0
    for i in range(1000):
        res*=i

if __name__ == '__main__':
    l = []
    s = []
    print(os.cpu_count())  # 本机为 8核
    start_time = time.time()
    for i in range(6):
        p = Process(target=work)
        t = Thread(target=work())
        l.append(p)
        s.append(t)
        p.start()
        t.start()
    for p in l:
        p.join()
    for t in s:
        t.join()
    stop_time = time.time()
    print(stop_time-start_time)
# 13.925952911376953

"""IO密集型"""
from multiprocessing import Process
from threading import Thread
import time,os

def work():
    time.sleep(2)

if __name__ == '__main__':
    p_list = []
    t_list = []
    start = time.time()
    for i in range(4000):
        p = Process(target=work)
        t = Thread(target=work)
        p_list.append(p)
        t_list.append(t)
        p.start()
        t.start()
    for p in p_list:
        p.join()
    for t in t_list:
        t.join()
    stop = time.time()
    print('run time is %s' % (stop - start))


"""
python的多线程到底有没有用
需要看情况而定  并且肯定是有用的


多进程+多线程配合使用
"""
1.GIL全局解释器锁.py
from threading import Thread
import time

n = 100


def task():
    global n
    tmp = n
    # time.sleep(1)
    n = tmp -1

t_list = []
for i in range(100):
    t = Thread(target=task)
    t.start()
    t_list.append(t)

for t in t_list:
    t.join()

print(n)
2.GIL与普通互斥锁.py
""""""
"""
Rlock 递归锁
可以被第一个抢到锁的人连续的acquire和release
每acquire一次锁身上的计数加1
每release一次锁身上的计数减1
只要锁的计数不为0 其他人都不能抢

"""
from threading import Thread,Lock,current_thread,RLock

# mutexA = Lock()
# mutexB = Lock()
mutexA = mutexB = RLock() # # A B现在是同一把锁


class MyThread(Thread):
    def run(self):# 创建线程自动触发run方法 run方法内调用func1 func2相当于也是自动触发
        self.func1()
        self.func2()
    def func1(self):
        mutexA.acquire()
        print(f'{self.name}抢到了A锁') # # self.name等价于current_thread().name
        mutexB.acquire()
        print(f'{self.name}抢到了B锁')
        mutexB.release()
        print(f'{self.name}释放了B锁')
        mutexA.release()
        print(f'{self.name}释放了A锁')

    def func2(self):
        mutexB.acquire()
        print(f'{self.name}抢到了B锁')  # # self.name等价于current_thread().name
        mutexA.acquire()
        print(f'{self.name}抢到了A锁')
        mutexA.release()
        print(f'{self.name}释放了A锁')
        mutexB.release()
        print(f'{self.name}释放了B锁')


for i in range(10):
    t = MyThread()
    t.start()


class Demo(object):
    pass

obj1 = Demo()
obj2 = Demo()
print(id(obj1),id(obj2))
# 2755671512512 2755671373248

"""
只要类加括号实例化对象
无论传入的参数是否一样生成的对象肯定不一样
单例模式除外


自己千万不要轻易的处理锁的问题  

"""
3.死锁.py
""""""
"""信号量可能在不同的领域中 对应不同的知识点"""
"""
互斥锁:一个厕所(一个坑位)
信号量:公共厕所(多个坑位)
"""
from threading import Semaphore,Thread
import time
import random
sm = Semaphore(5) # 造成一个含有五个坑位的公共厕所

def task(name):
    sm.acquire()
    print(f'{name}占了一个坑位')
    time.sleep(random.randint(1,3))
    sm.release()

for i in range(40):
    t = Thread(target=task,args=(i,))
    t.start()
4.信号量.py
from threading import Event,Thread
import time

# 先生成一个event对象

e = Event()

def light():
    print('红灯正亮着')
    time.sleep(3)
    e.set() # 发信号
    print('绿灯亮了')

def car(name):
    print(f'{name} 正在等红绿灯')
    e.wait() # 等待信号
    print(f'{name} 加油门飙车')

t1 = Thread(target=light)
t1.start()

for i in range(10):
    t = Thread(target=car,args=(f'伞兵{i}',))
    t.start()
5.event事件.py
""""""
"""
同一个进程下的多个线程本来就是数据共享 为什么还要用队列

因为队列是管道+锁  使用队列你就不需要自己手动操作锁的问题 

因为锁操作的不好极容易产生死锁现象
"""
import queue

# q = queue.Queue()
# q.put('hahha')
# print(q.get())

"""先进后出,其他方法与Queue一致"""
# q = queue.LifoQueue()
# q.put(1)
# q.put(2)
# q.put(3)
# print(q.get())

"""#  3.PriorityQueue 传入的参数要求是元组 '()'"""
"""数字越小,优先级越高"""
q = queue.PriorityQueue()
# q.put((10,'haha'))
# q.put((100,'hehehe'))
# q.put((0,'xxxx'))
# q.put((-10,'yyyy'))
# print(q.get())
6.线程q.py

 

posted on 2022-03-28 16:02  没有如果,只看将来  阅读(13)  评论(0编辑  收藏  举报