线程和多线程(未完待续)

线程和多线程

1.线程的实现

1.1.简介

在python中实现线程主要用到了两个模块,一个是_thread,另一个是threading,threading是对_thread模块进行了封装,所以实际情况我们一般都是用threading。

1.2.常用说明

1.target (表示要调用的子线程的对象)
2.name (线程的名字)
3.args (为位置参数,为元祖,特别注意当只有一个数的时候一定要在最后面加上,)


from threading import Thread  # threading 是Thread模块下的一个类,所以要用from调用
import time


def f1(person):  # 将要调用的子线程
    print("hello,{}".format(person))
    time.sleep(3)
    print("bye")

def f2(person):
    print("heihei,{}".format(person))
    time.sleep(3)
    print("godbye")


if __name__ == '__main__':
    f1_thread = Thread(target=f1, args=("thomas",))
    f2_thread = Thread(target=f2, args=("xiaohei",))
    f1_thread.start()  # 通过start来调用子线程
    f2_thread.start()
    f1_thread.join()  # 通过join来阻塞主线程,等子线程做完才能继续继续主线程
    f2_thread.join()
    print("主线程调用")

在这里插入图片描述
这是结果,我们知道,我们将子线程都睡了三秒,但是最后打印的依旧是主线程调用,所以可以看出join的作用所在。

这里还有一些实例用法
在这里插入图片描述
这个就是主要演示的是name方法,主要有两个,一个是setname,一个是getname,方法演示如图片所示
在这里插入图片描述
这是守护线程,通过守护线程来做到当主线程结束就全部结束了,就是接着往下跑,不等子线程了

1.3 Thread类的继承和改写

其实这里还有一个方法就是run方法,接下来通过一个类的改写来更加清楚的了解这个run方法是如何实现功能的。

from threading import Thread
import time


class My_Thread(Thread):
    def run(self):
        print("hello")
        time.sleep(3)
        print("bye")


if __name__ == '__main__':
    my_thread = My_Thread()
    my_thread.start()



这里就是通过类的继承改写原来的run方法,我们可以看到start是调用run方法。
在这里插入图片描述
这是代码及运行结果。

from threading import Thread
import time


class My_Thread(Thread):
    def __init__(self, people, *args, **kwargs):
        super().__init__(*args,**kwargs)
        self.people = people

    def run(self):
        print("hello,{}".format(self.people))
        time.sleep(3)
        print("bye")


if __name__ == '__main__':
    my_thread = My_Thread("thomas", name="lalal")
    print(my_thread.getName())
    my_thread.start()



如果你想改写这个类使用更灵活一点的话,在__init__这里一定要super().__init__这样的话才能继承原来的功能块中的功能,不然的话原来的功能就会被改写,而且会报错,这里一定要加上,*args,和**kwargs,这两个是动态数组,前面是元祖和列表,后面对应字典。
在这里插入图片描述
这是代码总览。
在这里插入图片描述
这是结果。

2.互斥锁

from threading import Thread,Lock

data = 0

def f1():
    global data
    for i in range(10000):
        data+= 1

def f2():
    global data
    for i in range(10000):
        data-= 1

if __name__ == '__main__':
    lock = Lock()
    t1 = Thread(target=f1())
    t2 = Thread(target=f2())
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print(data)

这里面是全局变量,多个线程的话一起修改全局变量,可能会打架,所以就有了互斥锁,这个操作系统里也讲过,如果不加这个锁的话,结果是未知的。
在这里插入图片描述
在这里插入图片描述
这里就是演示的结果了。

3.队列

# -*- coding: utf-8 -*-

from threading import Thread
from queue import Queue
from random import randint

my_queue = Queue(10)

def my_put(my_queue):
    for x in range(10):
        num = randint(0,1000)
        my_queue.put(num)

def my_get(my_queue):
    for y in range(3):
        num = my_queue.get()
        print(num)


if __name__ == '__main__':
    p = Thread(target=my_put, args=(my_queue,))
    g = Thread(target=my_get, args=(my_queue,))
    p.start()
    g.start()
    p.join()
    g.join()

在这里插入图片描述
在这里插入图片描述
这里就是演示一下关于队列的用法。这也是一种不打架的方式,队列就是数据结构中的一种数据类型。
接下来就是介绍一下队列的一些操作,其中主要包括task,这个是用来关闭put的,他们是一一对应的,有几个put就有几个task。

from queue import Queue

my_queue = Queue(3)

if __name__ == '__main__':
    my_queue.put(1)
    print(my_queue.qsize())  # 当前队列长度,1
    my_queue.get()
    print(my_queue.qsize())  # 当前队列长度,0
    my_queue.put(1)
    my_queue.put(1)
    my_queue.put(1)
    my_queue.task_done()
    my_queue.task_done()
    my_queue.task_done()
    my_queue.task_done()
    print(my_queue.full())  # 判断当前是否为满状态
    my_queue.join()  # 这个和之前是一样的,用来让主线程等待一下,用来判断task和put是否对等
    print("主线程已经结束了")


在这里插入图片描述
这个就是大致的演示结果,你不信的话可以试一试,如果没有task,你设置一下join,你发现进程是结束不了的。
(未完待续,还有一个线程池没写)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值