多线程理论和使用方法及其相关

JoinableQueue:

from multiprocessing import JoinableQueue,Queue

q = JoinableQueue()

q.put(1)
q.put(2)

print(q.get())

q.task_done() # 告诉容器已经处理完了一个数据
q.task_done() #有几个就要调用几次
#

q.join() # 也是一个阻塞函数 一直到队列中的数据被处理完毕 (task_done的调用次数等于队列中的数据数量)
print("处理完成")

# print(q.get())

 

线程
线程指的是一条流水线,是代码执行过程的总称  也是一个抽象概念
线程是CPU的最小执行单位  是具体负责执行代码的

进程是一个资源单位,其中包括了该程序运行所需的所有资源

线程的特点:
    一个进程中至少包含一个线程,是由操作系统自动创建的 称之为主线程
    一个进程中可以有任意数量的线程
    创建线程的开销对比进程而言 要小的多
    同一个进程中的线程间数据时共享的(最主要的特点)

如何使用: 使用的方式与进程一致
不同的是:创建线程的代码 可以写在任何位置

from threading import Thread
from multiprocessing import Process
# 第一种 开启线程的方式 直接实例化Thread类
def task():
    print("running.......")

if __name__ == '__main__':
    p = Process(target=task)
    p.start()
    # 开启线程速度 比开启进程快很多
    t = Thread(target=task)
    t.start()
    print("over")

2.继承Thread类  覆盖run方法

class MyThread(Thread):
    def run(self):
        print("running.......")

# if __name__ == '__main__':

MyThread().start()

t = MyThread()
t.start()

 

主线程 任务执行完毕后 进程不会立即结束 会等待所有子线全部执行完毕
在同一个进程中 所有线程都是平等的 没有子父这么一说

from threading import  Thread
import time

def task():
    print("子线程 running.....")
    time.sleep(3)
    print("子线程 over......")

t = Thread(target=task)
t.start()
print("main over")

 

from threading import  Thread
import time

# 与进程的区别之1  数据是共享的

a = 10

def task():
    global a
    time.sleep(0.5)
    a = -1
    print("子线程over....")

t = Thread(target=task)
t.start()
t.join()  # 阻塞函数 会一直等待子线程运行结束

print(a)
print("main over")

# 区别2 创建进程 与创建线程的开销 线程比进程快大约是一百多倍

from multiprocessing import  Process
import os
def task():
    print(os.getpid())
    pass

if __name__ == '__main__':

    start = time.time()
    ps = []
    for i in range(100):
        p = Thread(target=task)
        # p = Process(target=task)
        p.start()
        ps.append(p)

    for p in ps:
        p.join()

    print(time.time()-start)

 

线程安全也是通过锁来保证,锁的用法与进程中一模一样

import time
from threading import  Thread,Lock

num = 10
lock = Lock()

def task():
    global num
    lock.acquire()
    a = num
    time.sleep(0.1)
    num = a - 1
    lock.release()

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

for t in ts:
    t.join()

print(num)

 

当你今后在开发一些高并发程序是 很有可能出现线程/进程安全问题,
解决方案只有加锁 ,但是在使用锁时,很有可能出现死锁问题

出现死锁问题的两种情况
    1.对同一把锁调用了多次 acquire 导致死锁问题 (最low的死锁问题 )
    你应该避免在你代码中出现这种写法
    2.有多把锁,一个线程抢一把锁,要完成任务必须同时抢到所有的锁 ,这将导致死锁问题

 如何避免:
    1.能不加锁就不加
    2.如果一定要加 要保证锁只有一把

 

 

# Thread对象常用属性
t = Thread(name="一个线程")
print(t.name)
print(t.is_alive())#线程是否存活

print(t.daemon)#守护线程

print(t.ident)

# threading模块中常用属性

import threading
import os
# t = threading.current_thread() # 获取当前线程
# print(t)
#
# print(os.getpid())
#

# def task():
#     print(threading.current_thread())
#
# Thread(target=task).start()

print(threading.active_count() )# 正在运行中的线程数量
ts = threading.enumerate() # 返回所有正在运行的线程对象
print(ts)

 

守护线程会在主线程结束后立即结束 即使任务没有完成
主线程 会等待所有子线全部完成 后结束
守护线程会在所有非守护线程结束后 结束

主线   守护线程
主线程要等待所有子线结束

from threading import  Thread,current_thread
import time
def task1():
    print("%s 正在运行...." % current_thread().name)
    time.sleep(3)
    print("%s over...." % current_thread().name)

def task2():
    print("%s 正在运行...." % current_thread().name)
    time.sleep(10)
    print("%s over...." % current_thread().name)

t1 = Thread(target=task1)
t2 = Thread(target=task2)

t1.daemon = True

t1.start()
t2.start()
print("over")

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值