美文网首页
线程 二

线程 二

作者: 吃可爱长大鸭 | 来源:发表于2021-03-15 21:06 被阅读0次

目录

1.多进程与多线程效率对比
2.GIL与自定义线程锁的区别
3.多线程TCP客户端
4.多线程TCP服务端
5.线程池的使用
6.同步与异步
7.小结

1.多进程与多线程效率对比

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

# from threading import  Thread
# from multiprocessing import  Process
# import time
#
# a = 1
# def task():
#     global a
#     for i in range(10000000):
#         a +=1
#         a * 10 / 2 - 3
#
# s = time.time()
# #多线程
# # t1 = Thread(target=task)
# # t2 = Thread(target=task)
# # t3 = Thread(target=task)
#
# if __name__ == '__main__':
#
#     # 多进程
#     t1 = Process(target=task)
#     t2 = Process(target=task)
#     t3 = Process(target=task)
#     t1.start()
#     t2.start()
#     t3.start()
#
#     t1.join()
#     t2.join()
#     t3.join()
#
#     print(time.time() - s)
#


"""

    IO型任务
"""


from threading import  Thread
from multiprocessing import  Process
import time


def task():
    # for i in range(10):
    with open(r"D:\脱产5期内容\day34\视频\1.线程理论.mp4",mode="rb")as f:
        while True:
            data = f.read(1024)
            if not data:
                break

s = time.time()

if __name__ == '__main__':
    # 多线程
    t1 = Thread(target=task)
    t2 = Thread(target=task)
    t3 = Thread(target=task)

    # 多进程
    # t1 = Process(target=task)
    # t2 = Process(target=task)
    # t3 = Process(target=task)
    t1.start()
    t2.start()
    t3.start()

    t1.join()
    t2.join()
    t3.join()

    print(time.time() - s)

2.GIL与自定义线程锁的区别

from threading import  Thread,Lock
import time

lock = Lock()
a = 0
def task():
    global a
    lock.acquire()
    temp = a
    time.sleep(0.01)
    a = temp + 1
    lock.release()

ts = []
for i in range(10):
    t1 = Thread(target=task)
    t1.start()
    ts.append(t1)

for i in ts:
    i.join()

print(a)


"""
    GIL使用用于保护解释器相关的数据,解释器也是一段程序,肯定有其定义各种数据
    GIL并不能保证你自己定义的数据的安全,所以一旦你的程序中出现了多线程共享数据时就需要自己加锁 
    
"""

3.多线程TCP客户端

from threading import Thread
import socket

c = socket.socket()
c.connect(("127.0.0.1",8989))

def send_msg():
    while True:
        msg = input(">>>:")
        if not msg:
            continue
        c.send(msg.encode("utf-8"))

send_t = Thread(target=send_msg)
send_t.start()

while True:
    try:
        data = c.recv(1024)
        print(data.decode("utf-8"))
    except:
        c.close()
        break

4.多线程TCP服务端

from concurrent.futures import ThreadPoolExecutor
from threading import  Thread
import socket

server = socket.socket()
server.bind(("127.0.0.1",8989))
server.listen()


pool = ThreadPoolExecutor(3)

def task(client):
    while True:
        try:
            data = client.recv(1024)
            if not data:
                client.close()
                break
            client.send(data.upper())
        except Exception:
            client.close()
            break

while True:
    client,addr = server.accept()
    # t = Thread(target=task,args=(client,))
    # t.start()
    pool.submit(task,client)

5.线程池的使用

from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
from  threading import active_count,current_thread
import os,time
# 创建线程池 指定最大线程数为3  如果不指定 默认为CPU核心数 * 5
# pool = ThreadPoolExecutor(3)# 不会立即开启子线程
#
# print(active_count())
#
# def task():
#     print("%s running.." % current_thread().name)
#     time.sleep(1)
#
# #提交任务到线程池
# for i in range(10):
#     pool.submit(task)
#


# 创建进程池 最大进程数为3 默认为cpu个数
pool = ProcessPoolExecutor(3)# 不会立即开启子进程

# time.sleep(10)

def task():
    print("%s running.." % os.getpid())
    time.sleep(1)

if __name__ == '__main__':
    # #提交任务到进程池
    for i in range(10):
        pool.submit(task) # 第一次提交任务时会创建进程  ,后续再提交任务,直接交给以及存在的进程来完成,如果没有空闲进程就等待


# 与信号量的区别 ,信号量也是一种锁 适用于保证同一时间能有多少个进程或线程访问
# 而线程/进程池,没有对数据访问进行限制仅仅是控制数量

6.同步与异步

"""
阻塞 非阻塞
程序遇到了IO操作,无法继续执行代码,叫做阻塞
程序没有遇到IO操作,正常执行中,就叫非阻塞
它们指的是程序的状态

    就绪  运行  阻塞

就绪和阻塞给人的感觉就是卡主了


同步 异步
同步(调用/执行/任务/提交),发起任务后必须等待任务结束,拿到一个结果才能继续运行
异步                     发起任务后不需要关系任务的执行过程,可以继续往下运行

异步效率高于同步
但是并不是所有任务都可以异步执行,判断一个任务是否可以异步的条件是,任务发起方是否立即需要执行结果


同步不等于阻塞  异步不等于非阻塞
当使用异步方式发起任务时 任务中可能包含io操作  异步也可能阻塞
同步提交任务 也会卡主程序 但是不等同阻塞,因为任务中可能在做一对计算任务,CPU没走
"""

# 使用线程池 来执行异步任务
from multiprocessing import Process
from concurrent.futures import ThreadPoolExecutor
import time
pool = ThreadPoolExecutor()


def task(i):

    time.sleep(1)
    print("sub thread run..")
    i += 100
    return i

fs = []
for i in range(10):
    f = pool.submit(task,i) # submit就是一异步的方式提交任务
    # print(f)
    # print(f.result()) # result是阻塞的 会等到这任务执行完成才继续执行 ,会异步变成同步
    fs.append(f)



# 是一个阻塞函数,会等到池子中所有任务完成后继续执行
pool.shutdown(wait=True)

# pool.submit(task,1) # 注意 在shutdown之后 就不能提交新任务了

for i in fs:
    print(i.result())

print("over")

7.小结

1.GIL锁
    是什么 加在解释器上的互斥锁
    干什么 用来防止多个线程同一时间使用解释器
    为什么 因为CPython的内存管理是非线程安全
    有什么影响  无法利用多核优势,但不影响并发

    正因为无法并行执行,所以有了多进程

    多线程与多线程的区别?
     1.进程消费资源高 而线程低
     2.进程的数据相互隔离,同一进程中的线程数据是共享的


    GIL仅存在与CPython中 其他解释器没有这个问题.但是由于CPython优势在于有大量的C的库可以调用,所以目前为止依然CPython独领风骚

    之所以学习GIL锁 是为了能用最合适的方式来完成你的任务
    对于IO密集型任务,应该交给多线程
    对于计算密集型任务,应该交给多进程

    在单核CPU下,GIL不会对效率产生任何影响



2.进程池与线程池
    是什么  存放线程或进程的容器
    为什么需要  一个程序中不可能无限的开启线程或进程,所以我们需要用池子来限制线程或进程的数量
              除了控制数量 池子还帮我们 管理 进程的创建  销毁  以及任务的分配

3.同步和异步
    同步 任务开启后必须立即获取它的结果
    异步 任务开启后完全不用关系任务的执行过程,可以立即执行后续代码

4.自定义锁与GIL的区别
    自定义锁 用于保证多个线程中自己定义共享数据的安全性
    GIL 锁 用于保证解释器级别的共享数据的安全性

相关文章

  • 主线程子线程事务同步

    一、主线程 二、子线程

  • juc9-Executors

    0 线程池类图 一 ForkJoinPool 分治线程池 二 ThreadPoolExecutor 固定线程数线程...

  • Linux下多线程的使用

    一、线程的创建 1.创建分离线程方法一:(常用) 方法二: 2.创建非分离线程 二、线程的使用 三、分离线程与非分...

  • 多线程介绍

    一、进程与线程 进程介绍 线程介绍 线程的串行 二、多线程 多线程介绍 多线程原理 多线程的优缺点 多线程优点: ...

  • Java 多线程之线程的创建及其使用

    一、创建线程以及启动线程 二、停止线程 三、线程类中函数详解 一、创建线程以及启动线程 创建线程:Java中创建线...

  • 多线程方法

    一. 基础并行多线程结构 二. 标准多线程方法,控制并发线程数,带线程锁

  • 多线程基本概念

    一、什么进程 二、什么线程 三、什么是多线程 四、主线程和子线程 主线程: 子线程: 多线程的优缺点优点: 缺点 ...

  • Day19——threading

    一、导入线程库 二、创建子线程 函数创建线程 Thread(target,args) - 创建子线程对象说明...

  • iOS多线程:NSThread

    目录一,线程创建二,线程通信三,线程状态 一,线程创建 1,实例方法 initWithTarget: initWi...

  • Python爬虫第六天:进程-线程-互斥锁-同步异步-队列-生产

    内容简述: 一:初始线程、进程 二:进程和线程的区别 三:线程的调用方式 四:线程安全与线程锁 ...

网友评论

      本文标题:线程 二

      本文链接:https://www.haomeiwen.com/subject/ydslcltx.html