python_多线程

为什么使用多线程?

1.进程之间不能共享内存,但是线程之间可以共享内存

2.创建进程需要重新分配内存,但是创建线程代价很小

3.python内置多线程模块

 

Threading模块

1.自定义线程

本质:继承threading.Thread,重构thread中的run方法

2.守护线程

setDaemon(True),把所有的子线程都变成了主线程的守护线程,意思是主进程结束,子线程就会直接强制结束

3.主线程等待子线程结束

为了让守护线程结束之后,主程序再结束,我们使用join方法,让主线程等待子线程执行

import threading
import time

def run(n):
    print("task", n)
    time.sleep(1)       #此时子线程停1s
    print('3')
    time.sleep(1)
    print('2')
    time.sleep(1)
    print('1')

if __name__ == '__main__':
    t = threading.Thread(target=run, args=("t1",))
    t.setDaemon(True)   #把子进程设置为守护线程,必须在start()之前设置
    t.start()
    t.join() # 设置主线程等待子线程结束
    print("end")

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

>>> task t1
>>> 3
>>> 2
>>> 1
>>> end

--global设定变量为全局变量,函数中修改变量改变全局

4.多线程共享全局变量

线程是进程的执行单元,进程是系统分配资源的最小单位,所以同一个进程中的多线程是共享资源的

import threading
import time

g_num = 100

def work1():
    global g_num
    for i in range(3):
        g_num += 1
    print("in work1 g_num is : %d" % g_num)

def work2():
    global g_num
    print("in work2 g_num is : %d" % g_num)

if __name__ == '__main__':
    t1 = threading.Thread(target=work1)
    t1.start()
    time.sleep(1)
    t2 = threading.Thread(target=work2)
    t2.start()

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

>>> in work1 g_num is : 103
>>> in work2 g_num is : 103

可以看到线程2是直接拿线程1的g_num直接使用的,可以看出线程之间共享了变量

5.互斥锁(lock)

由于线程是随机调用的,所以多个线程修改一个数据时,会出现脏数据。

线程锁可以锁定资源,这样就可以就避免多个操作对一个数据,资源就是变量

6.信号量

互斥锁只允许一个操作修改数据,信号量允许多个线程去修改数据

7.事件(event类)

 

 

最近因为要经常的开发一些实战工具,现有的线程知识储备还是太少了,决定继续结合着现在正在学的操作系统进行个深入的研究。、

1 .首先之前用的多线程的思想都是面向过程的,说人话就是没有进行一次对线程对象的封装,封装之后会使得代码结构更加的清晰(我的理解)

所以这里对我的知识体系中引入mythread类,这个mythread应该是继承thread类的,同时我们应该重写里面的run方法,举个例子方便下自己理解吧 。

import threading
import time
#其实这里就可以看出封装线程可以将你要完成的子任务以更加清晰的方式去存放在类里面,极大的整合了代码结构
class mythread(threading.Thread):
     def __init__(self,arg):
         super(mythread,self).__init__()#显式调用父亲的初始化函数
         self.arg = arg
     def run(self):
        time.sleep(1)
        print('现在是第%d线程' %self.arg)
for i in range(4):
     t = mythread(i)
     t.start()
print('main thead start')

2.将线程进行封装之后,以面向对象的思想整合好多线程结构之后呢,再去思考下线程之间的通信问题,那么我们怎么去设计多线程中的一套消费者生产者模型呢?在python3 中呢,我们可以使用Queue,进行队列操纵,将要完成的任务放在队列中,然后给线程去进行使用。

其实呢,我的理解就是,将需要做的任务放在队列中,需要做什么 ,就开一个线程直接去做队列里面的事情,说白了,把要做的事情,放在一个数组里面,然后让线程接受的数据也是一个数组数据。 

所以引入quque这个概念到底给我们带来了什么呢?总结一下,将设计师和工人分开,可以更加好的去管理工人的一些事项的进行。

for i in range(x):
  t = MyThread(queue)
  t.start()

今天没空,明天再补吧,先去刷ctf去了。

 

posted @ 2021-09-02 22:14  Lzwhehe  阅读(93)  评论(0)    收藏  举报