学习笔记-线程

本文详细解读了进程和线程的概念,包括进程的动态执行、资源管理和调度,以及线程作为最小调度单元的特点。讲解了主线程、创建线程的方法(run(), start(), join()),以及自定义线程和线程锁的重要性。通过实例演示了多线程卖票问题及其解决方案,突出了线程同步的必要性。
摘要由CSDN通过智能技术生成

什么是进程:
进程是程序的一次动态执行过程,每个进程度拥有自己的地址空间、内存、数据栈一技其他用于跟踪执行的辅助数据
操作系统负责其上所有的进程的执行,操作系统会位这个进程合理的分配执行时间
什么是线程:
线程是操作系统能够进行运算的调度的最小单位,它被包含在进程之中,是进程中的实际运作单位
一个线程只得是进程中一个单一的控制流,一个进程中可以并发多个线程,每条线程执行不同的任务
一个线程是一个execution context(执行上下文),即一个cpu执行时所需要的一串指令
主线程:
线程就是创建进程的第一个线程,也就是main函数对应的线程

创建线程
需要导入threading模块
from threading import Thread
t3 = Thread(target=task3) #创建一个线程对象
线程中的方法
run() # 运行线程,仅仅是普通函数调用,如果使用run方法启动线程,无法达到多线程的目的
start() # 执行开始线程
join() # 线程阻塞,执行完当前线程才执行后面的
name 查看线程名,默认的线程名Thread-1,第二个Thread-2…
is_alive() # 判断当前线程是否存活
在线程中,如果有全局变量是每个线程之间共享,这样就有一个问题:就是可能我不同的线程在重复处理一件事,所有需要使用线程锁
线程创建的代码示例

# encoding: utf-8
from threading import Thread, current_thread, Lock


def task3():
    for i in range(5):
        print("正在进行task3函数的第{}次任务".format(i), os.getpid(), os.getppid())
        time.sleep(0.5)

def task4(n):
    for i in range(n):
        print("正在进行task4函数的第{}次任务".format(i), os.getpid(), os.getppid())
        time.sleep(0.5)
if __name__ == '__main__':
	t3 = Thread(target=task3, name="task3")               # 创建线程对象,name配置线程名
    t4 = Thread(target=task4, args=(6, ))                    
    t3.start()              # 启动线程
    t4.start()
    print(t3.is_alive())           # 判断线程是否存活
    print(t4.is_alive())
    t3.join()               # 阻塞线程
    t3.join()               

自定义线程即重写线程
自定义线程与重写进程类似,也是通过创建新的线程类,然后使用新的线程类继承Thread的方法实现,再重写run方法即可
代码示例

# encoding: utf-8
from threading import Thread, current_thread, Lock

class MyThread(Thread):
    def __init__(self, name):
        Thread.__init__(self)
        self.name = name
    def run(self):
        for i in range(5):
            print("正在进行自定义线程中的第{}次任务".format(i), os.getpid(), os.getppid())
            time.sleep(0.5)
if __name__ == '__main__':
	t5 = MyThread(name="自定义线程")                     # 创建自定义线程对象并指定线程名
    t5.start()                          # 启动自定义线程对象
    t5.join()
    print("t5线程名::",t5.name)                      # 查看当前线程名

输出结果

正在进行自定义线程中的第0次任务 70502 390
正在进行自定义线程中的第1次任务 70502 390
正在进行自定义线程中的第2次任务 70502 390
正在进行自定义线程中的第3次任务 70502 390
正在进行自定义线程中的第4次任务 70502 390
t5线程名:: 自定义线程

通过多线程实现卖票代码示例(代码中)

# encoding: utf-8
from threading import Thread, current_thread, Lock
ticket = 10

def sale_ticket():
    global ticket
    while True:
        if ticket > 0:
            print("{}正在出售第{}张票".format(current_thread().name, ticket))
            ticket -= 1
            time.sleep(0.5)
        else:
            print("{}提示:票卖完了!!".format(current_thread().name))
            break
if __name__ == '__main__':
	t6 = Thread(target=sale_ticket, name="一号窗口")            # 创建线程对象,并指定线程名
    t7 = Thread(target=sale_ticket, name="二号窗口")
    t8 = Thread(target=sale_ticket, name="三号窗口")
    t9 = Thread(target=sale_ticket, name="四号窗口")
    t10 = Thread(target=sale_ticket, name="五号窗口")
    t6.start()                              # 启动线程
    t7.start()
    t8.start()
    t9.start()
    t10.start()

输出结果

一号窗口正在出售第10张票
二号窗口正在出售第9张票
三号窗口正在出售第8张票
四号窗口正在出售第7张票
五号窗口正在出售第6张票
二号窗口正在出售第5张票
四号窗口正在出售第4张票			# 在线程执行过程中可能会出现类似问题
一号窗口正在出售第4张票
三号窗口正在出售第2张票
五号窗口正在出售第1张票
二号窗口提示:票卖完了!!
四号窗口提示:票卖完了!!
一号窗口提示:票卖完了!!
三号窗口提示:票卖完了!!
五号窗口提示:票卖完了!!

可以从输出结果中看出,代码在执行时会出现重复卖的票与漏卖的,这是因为线程在执行时使用的是一个全局变量,就会出现不同线程在同一时间处理同一个任务。解决这一办法就是为线程加上一个GIL锁,下篇笔记记述线程锁的使用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值