线程--(python21)

1. 线程的介绍

线程是进程中执行代码的一个分支,每个执行分支(线程)要想工作执行代码需要cpu进行调度 ,也就是说线程是cpu调度的基本单位,每个进程至少都有一个线程,而这个线程就是我们通常说的主线程。

实现:
首先要进行模块的导入
import threading

"""
实现多任务的另一种方式
进程:资源分配
线程:cpu调度的最小单位

线程实现多任务
"""


import threading
import time


def task1():
    th1 = threading.current_thread()
    print('th', th1)
    for i in range(5):
        print('task1--', i)
        time.sleep(0.5)


def task2():

    th2 = threading.current_thread()
    print('th', th2)
    for i in range(5):
        print('task2--', i)
        time.sleep(0.5)


if __name__ == '__main__':
    # 获取线程的的对象
    th = threading.current_thread()
    print('th', th)
    # 创建线程
    t1 = threading.Thread(target=task1, name='t1')
    t2 = threading.Thread(target=task2, name='t2')
    # 未执行之前
    print(t1)
    print(t2)
    # 启动线程
    t1.start()
    t2.start()
    # 执行以后
    print(t1)
    print(t2)

1.2 多线程的实现方式

Thread类的参数说明

Thread([group [, target [, name [, args [, kwargs]]]]])

group: 线程组,目前只能使用None
target: 执行的目标任务名
args: 以元组的方式给执行任务传参
kwargs: 以字典方式给执行任务传参
name: 线程名,一般不用设置

agrs与kwagrs传参

"""
线程之间的执行顺序是无序的
"""


import threading
import time


def task1(count):
    for i in range(count):
        print('task1--', i)
        time.sleep(0.5)


def task2(con, count):
    for i in range(count):
        print(con, i)
        time.sleep(0.5)


if __name__ == '__main__':
    # 获取线程的的对象
    th = threading.current_thread()
    print('th', th)

    # 创建线程
    # 传参的方式args  元组
    # t1 = threading.Thread(target=task1,name='t1',args=(5,))
    # t2 = threading.Thread(target=task2,name='t2',args=('hello',5))
    # kwargs的方式  字典的形式
    t1 = threading.Thread(target=task1, name='t1', kwargs={'count': 5})
    t2 = threading.Thread(target=task2, name='t2', kwargs={'count': 5, 'con': 'hello'})
    t1.start()
    t2.start()

1.3 线程的注意事项

线程之间执行是无序的
主线程会等待所有的子线程执行结束再结束
线程之间共享全局变量
线程之间共享全局变量数据出现错误问题

设置守护主线程

"""
主线程执行完,子线程自动销毁
"""


import threading
import time


def task():
    for i in range(5):
        print(i)
        time.sleep(0.5)


if __name__ == '__main__':
    # 方式一
    # t1 = threading.Thread(target=task,daemon=True)
    t1 = threading.Thread(target=task)
    # 方式二 都要设置在start之前
    t1.setDaemon(True)
    t1.start()
    time.sleep(1)
    print('over')

1.4 线程之间共享全局变量

"""
线程在进程里边,调用线程的资源,所以线程是共享资源的
而进程是相互独立的,不进行数据的共享
进程间的资源是独立的
"""


import threading
import time

m_list = []


def add_data():
    for i in range(5):
        print(i)
        m_list.append(i)
        time.sleep(0.5)
    print('add:', m_list)


def read_data():
    print('read:', m_list)


if __name__ == '__main__':
    t1 = threading.Thread(target=add_data)
    t2 = threading.Thread(target=read_data)

    t1.start()
    t1.join()
    t2.start()
    print('main', m_list)

共享数据之间的资源竞争问题

"""

"""

import threading
import time

m_sum = 0


def task1():
    for _ in range(1000000):
        global m_sum
        m_sum += 1
    t = threading.current_thread()
    print(f'{t.name} 结果: {m_sum}')


if __name__ == '__main__':
    t1 = threading.Thread(target=task1)
    t2 = threading.Thread(target=task1)
    t1.start()
    t2.start()
    time.sleep(5)
    print('main', m_sum)

解决办法:互斥锁的应用
方式一:线程同步


import threading
import time

m_sum = 0


def task1():
    global m_sum
    for _ in range(1000000):
        m_sum += 1
    t = threading.current_thread()
    print(f'{t.name} 的执行结果{m_sum}')


if __name__ == '__main__':
    t1 = threading.Thread(target=task1)
    t2 = threading.Thread(target=task1)
    t1.start()
    # 方式1  join  线程同步,t1执行完在执行t2
    # 弊端:效率不高
    t1.join()
    t2.start()

    time.sleep(2)

    print('main', m_sum)

方式二:互斥锁

"""
加锁解决问题
"""

import threading
import time

m_sum = 0

# 创建一个锁
th_lock = threading.Lock()


def task1():
    global m_sum
    # 加锁
    th_lock.acquire()
    for _ in range(1000000):
        m_sum += 1
    # 解锁
    th_lock.release()

    t = threading.current_thread()
    print(f'{t.name} 的执行结果: {m_sum}')


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

    time.sleep(2)

    print('main', m_sum)

加锁异步

"""
加锁解决问题
锁的位置不同
"""

import threading
import time

m_sum = 0

# 创建一个锁
th_lock = threading.Lock()


def task1():
    global m_sum
    for _ in range(1000000):
        # 加锁 加到里边会产生效率的问题
        th_lock.acquire()
        m_sum += 1
        # 解锁
        th_lock.release()
    t = threading.current_thread()
    print(f'{t.name} 的执行结果: {m_sum}')


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

    time.sleep(2)

    print('main', m_sum)

1.5 死锁的产生

一直在等待对方的先进行的方式

"""

"""

import threading

my_list = [1, 2, 3]
# 创建一个锁
t_look = threading.Lock()


def task(index):
    t1 = threading.current_thread()
    # 加锁
    t_look.acquire()
    if index >= len(my_list):
        print('超出下标的范围')
        # 解锁
        t_look.release()
        return
    print(f'{t1.name}的取第{index}个的值为{my_list[index]}')
    # 解锁 只加一个会出现死锁的问题
    t_look.release()


if __name__ == '__main__':
    for i in range(5):
        t = threading.Thread(target=task, args=(i,))
        t.start()

2.进程与线程的对比

关系:

线程是依附在进程里面的,没有进程就没有线程。
一个进程默认提供一条线程,进程可以创建多个线程。

区别:

进程之间不共享全局变量
线程之间共享全局变量,但是要注意资源竞争的问题,解决办法: 互斥锁或者线程同步
创建进程的资源开销要比创建线程的资源开销要大
进程是操作系统资源分配的基本单位,线程是CPU调度的基本单位
线程不能够独立执行,必须依存在进程中
多进程开发比单进程多线程开发稳定性要强

进程优缺点:
优点:可以用多核
缺点:资源开销大
线程优缺点:
优点:资源开销小
缺点:不能使用多核

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长安有故里y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值