Python------多线程

Python从入门到高手(内部资源-配学习资料)_哔哩哔哩_bilibili

# 线程是进程中的一个实体,可与同属一个进程的其他线程共享进程所拥有的全部资源。多个线程之间可以并发执行。
# 线程是程序中一个单一顺序控制流程。
''':cvar
线程状态:
新建状态---start---就绪---运行---结束
                   \     /
                    sleep(n)
                    阻塞
线程是可以共享全局变量
'''
import threading

# 进程 Process
# 线程 Thread
from time import sleep


def download(n):
    images = ['girl.jpg', 'boy.jpg', 'man.jpg']
    for image in images:
        print('正在下载:', image)
        sleep(n)
        print('下载{}成功'.format(image))


def listenMusic():
    musics = ['大碗宽面', '土耳其冰淇淋', '烤面筋', '烤馒头片']
    for music in musics:
        sleep(0.5)
        print('正在听{}歌'.format(music))


if __name__ == '__main__':

    # 线程对象
    t = threading.Thread(target=download, name='aa', args=(1,))
    t.start()

    # 线程对象
    t1 = threading.Thread(target=listenMusic, name='aa')
    t1.start()

    n = 1
    while True:
        print(n)
        sleep(1.5)
        n += 1

-------------------------------------------------------------------------------------------------------------------

''':cvar
线程可以共享全局变量
GIL 全局解释器锁
线程:耗时操作,爬虫,IO
进程:计算密集型
'''
import threading

n = 0


def task1():
    global n
    for i in range(10000000):
        n += 1
    print('------------->task1中的n值是:', n)


def task2():
    global n
    for i in range(10000000):
        n += 1
    print('------------->task2中的n值是:', n)


if __name__ == '__main__':
    th1 = threading.Thread(target=task1)
    th2 = threading.Thread(target=task2)
    th1.start()
    th2.start()
    th1.join()
    th2.join()
    print("最后打印", n)

-----------------------------------------------------------------------------------------------------------

有共享数据需要加lock,保证数据安全

''':cvar
使用Thread对象的Lock和Rlock可以实现简单的线程同步,对这两个对象都有acquire和release方法,对每次只允许一个线程操作的数据,可以将
其操作放到acquire和release方法之间
多线程的又是在于可以同时运行多个任务
lock=threading.Lock()
lock.acquire() 请求得到锁
...
lock release() 释放锁

只要不释放其他线程都无法进入运行状态
'''
import threading
import random
import time

lock = threading.Lock()
list1 = [0] * 10


def task1():
    # 获取线程锁,如果已经上锁,则等待锁的释放
    lock.acquire()  # 阻塞
    for i in range(len(list1)):
        list1[i] = 1
        time.sleep(0.5)
    lock.release()


def task2():
    lock.acquire()  # 阻塞
    for i in range(len(list1)):
        print('------>', list1[i])
        time.sleep(0.5)
    lock.release()


if __name__ == '__main__':
    t1 = threading.Thread(target=task1)
    t2 = threading.Thread(target=task2)

    t2.start()
    t1.start()

    t2.join()
    t1.join()
    print(list1)

-----------------------------------------------------------------------------------------------------------------

''':cvar
死锁
开发过程中使用线程,在线程间共享多个资源是,如果两个线程分别占有一部分资源并且同时等待对方资源,就会造成死锁
尽管死锁很少发生,但一旦发生就会造成应用的停止响应,程序不做任何事情

避免死锁:
解决:
1.重构代码
2.使用timeout参数
'''

from threading import Thread, Lock
import time

lockA = Lock()
lockB = Lock()


class MyThread(Thread):
    def run(self):  # start()
        if lockA.acquire():  # 如果可以获取到锁则返回True
            print(self.name + '获取了A锁')
            time.sleep(0.1)
            if lockB.acquire(timeout=5):  # 阻塞
                print(self.name + '又获取了B锁,原来还有A锁')
                lockB.release()
            lockA.release()


class MyThread1(Thread):
    def run(self):  # start()
        if lockB.acquire():  # 如果可以获取到锁则返回True
            print(self.name + '获取了B锁')
            time.sleep(0.1)
            if lockA.acquire(timeout=5):
                print(self.name + '又获取了A锁,原来还有B锁')
                lockA.release()
            lockB.release()


if __name__ == '__main__':
    t1 = MyThread()
    t2 = MyThread1()

    t1.start()
    t2.start()

----------------------------------------------------------------------------------------------------------------------

''':cvar
生产者与消费者:两个线程之间的通信
Python的queue模块中提供了同步的、线程安全队列类,包括FIFO(先入先出)队列Queue,
LIFO(后入先出)队列LifoQueue,和优先级队列PriorityQueue。这些队列都实现了锁
原语(可以理解为原子操作,即要么不做,要做就做完),能够在多线程中直接使用,可以使用队列
来实现线程间的同步。

'''
import threading
import queue
import random
import time


def produce(q):
    i = 0
    while i < 10:
        num = random.randint(1, 100)
        q.put('生产者产生数据:%d' % num)
        print("生产者产生数据:%d" % num)
        time.sleep(1)
        i += 1
    q.put(None)
    # 完成任务
    q.task_done()


def consume(q):
    while True:
        item = q.get()
        if item is None:
            break
        print("消费者获取到:%s" % item)
        time.sleep(4)
    # 完成任务
    q.task_done()


if __name__ == '__main__':
    q = queue.Queue(10)
    arr = []
    # 创建生产者
    th = threading.Thread(target=produce, args=(q,))
    th.start()

    # 创建消费者
    tc = threading.Thread(target=consume, args=(q,))
    tc.start()

    # 完成任务
    th.join()
    tc.join()
    print('END')

''':cvar
线程:Thread
1.创建线程
A t=Thread(target=func,args=(),kwargs=())  新建状态
t.start()--->就绪状态
run()
join()
B 自定义
class MyThread(Thread):
    def __init__(self,name):
        super().__init__()
        self.name=name
    def run(self):
        任务
    
    t=MyThread()
    t.start()
    
2.数据共享
进程共享数据与线程共享数据区别:
进程是每个进程中都有一份
线程是共同一个数据--->数据安全性问题
GIL---伪线程
避免死锁

3.线程间通信:生产者与消费者
生产者:线程
消费者:线程
import queue
q=queue.Queue()
q.put()
q.get()
扩展:GUI
'''
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值