首页 > 编程语言 > 详细

线程的其他知识点

时间:2019-08-14 22:22:19      阅读:79      评论:0      收藏:0      [点我收藏+]

---恢复内容开始---

不使用socketserver模块实现 tcp协议服务端的并发

技术分享图片
import socket
from threading import Thread

s = socket.socket()

s.bind((127.0.0.1, 56984))
s.listen(5)


def server_while(conn):
    while True:
        try:
            data = conn.recv(1024)
            print(data.decode(utf-8))
            conn.send(data.upper())
        except ConnectionResetError as c:
            print(c)
            break
    conn.close()

if __name__ == __main__:
    while True:
        conn, addr = s.accept()
        t = Thread(target=server_while, args=(conn,))
        t.start()
服务端
技术分享图片
import socket

client = socket.socket()
client.connect((127.0.0.1,56984))

while True:
    client.send(bsdjflaasdfad)
    data = client.recv(1024)
    print(data)
服务端

GIL全局解释器锁

ps:python解释器有很多种 最常见的就是Cpython解释器

GIL本质也是一把互斥锁:将并发变成串行牺牲效率保证数据的安全    用来阻止同一个进程下的多个线程的同时执行(同一个进程内多个线程无法实现并行但是可以实现并发

   问 python的多线程没法利用多核优势 是不是就是没有用了?   答  python的多线程到底有没有用需要看情况而定 并且肯定是有用的  一般 多进程+多线程配合使用

 

GIL的存在是因为CPython解释器的内存管理不是线程安全的

 

什么是内存管理(代码申请代码释放 相当于 with open close)

垃圾回收机制 

  1.引用计数:内存中的数据如果没有任何的变量名与其有绑定关系,那么会被自动回收

  2.标记清除:当内存快要被某个应用程序占满的时候,会自动触发

  3.分代回收:根据值得存活时间的不同,划为不同的等级,等级越高垃圾回收机制扫描的频率越低

技术分享图片

技术分享图片

继续问  python的多线程没法利用多核优势 是不是就是没有用了?

研究python的多线程是否有用需要分情况讨论
  四个任务 计算密集型的 
    单核情况下
      开线程更省资源 (单核的话 进程 和 线程 都可以并发 但是 线程 更省资源)
    多核情况下   一次任务 10秒 
      开进程 10s (进程可以并行 同时运行4个 进程同时计算)
      开线程 40s (需要计算4次的时间才能计算完)

  四个任务 IO密集型的
    单核情况下
      开线程更节省资源(都要等 所有线程节省资源)
    多核情况下
      开线程更节省资源(即使进程可以并行 但是也需要等  而 线程 可以并发 相差不大 所以使用 线程节省资源)

from threading import Thread
import time

n = 100

def task():
    global n
    tmp = n
    time.sleep(1) #相当释放了锁 release
    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)

 死锁

技术分享图片

RLock   (from threading import Thread,Lock,RLock)  又叫递归锁

Rlock可以被第一个抢到锁的人连续的acquire和release
每acquire一次锁身上的计数加1
每release一次锁身上的计数减1
只要锁的计数不为0 其他人都不能抢

技术分享图片
from threading import RLock,Thread

mutex = RLock()

class MyThread(Thread):
    def __init__(self, name):
        super().__init__()
        self.name = name

    def run(self):
        mutex.acquire()
        print({}抢到了锁.format(self.name))
        mutex.acquire()
        print({}抢到了锁.format(self.name))
        mutex.acquire()
        print({}抢到了锁.format(self.name))
        mutex.acquire()
        print({}抢到了锁.format(self.name))
        
        mutex.release()
        print({}释放了锁.format(self.name))
        mutex.release()
        print({}释放了锁.format(self.name))
        mutex.release()
        print({}释放了锁.format(self.name))
        mutex.release()
        print({}释放了锁.format(self.name))

if __name__ == __main__:
    for i in range(10):
        t = MyThread(i)
        t.start()
递归锁

信号量 (信号量可能在不同的领域中 对应不同的知识点  例如Django)

互斥锁:一个厕所(一个坑位)

信号量:公共厕所(多个坑位)

from threading import Semaphore,Thread
import time
import random


sm = Semaphore(5)  # 造了一个含有五个的坑位的公共厕所  使用方法和 LOCK一样 生成对象

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

for i in range(40):
    t = Thread(target=task,args=(i,))
    t.start()

抢到锁的人执行完后走了 马上就会有人来了

event事件

方法 : set wait Event

生成对象 e = Event

技术分享图片

复习 queue模块 

同一个进程下的多个线程本来就是数据共享 为什么还要用队列
因为队列是管道+锁 使用队列你就不需要自己手动操作锁的问题
因为锁操作的不好极容易产生死锁现象

q = queue.Queue() 方法  put get  取完原地等待

q = queue.LifoQueue()  last in fast out 后进 先出  

技术分享图片

q = queue.PriorityQueue()  put() 里面放的是元组   数字越小 优先级越高  例如 (-5, ‘哈哈哈‘)

 

线程的其他知识点

原文:https://www.cnblogs.com/lddragon/p/11354368.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!