美文网首页
Python多线程

Python多线程

作者: 晨畿茨 | 来源:发表于2018-07-26 10:27 被阅读0次

Python多线程

多任务不仅可以使用多进程完成,也可使用多线程完成。
一个进程可以包含很多线程,但至少含有一个线程。

Python提供了 _thread和threading两个模块,供我们使用多线程。_thread是低级模块,threading是高级模块。我们通常使用threading来实现多线程的相关功能。

使用线程读取文件内容。

  1. 读取文件内容的方法
  2. 创建线程,并将方法绑定到线程上
#!/usr/bin/env python3
# -*- coding:utf-8 -*-  
'多线程'
__author__ = 'click'
__date__ = '2018/7/23 下午6:20'

import time, threading


def threadReadFile():
    print('主线程的名字%s' % threading.current_thread().name)
    # print('读取文件中内容是%s' % myio.ReadAndWrite.readTxt())
    n = 0
    while n < 10:
        n = n + 1

    print('执行相加操作结果是%s' % n)


t = threading.Thread(target=threadReadFile, name='threadReadFile')
t.start()
t.join()
print("当前线城是%s" % threading.current_thread().name)

运行结果:

主线程的名字threadReadFile
执行相加操作结果是10
当前线城是MainThread

使用线程之前,先<font color = red >import threading</font>要使用的threading模块。

t = threading.Thread(target=threadReadFile, name='threadReadFile')

初始化一个线程。

target:指定线程要执行的任务。

name:创建的线程的名称。

这样就实现了新创建一个线程,执行新任务。

提到多线程,就要考虑多线程之间操作同一变量时候,出现<font color = red >脏数据</font>的问题。

来看看多线程是怎么样操作变量数据,导致多线程获取数据时候出错的。

#!/usr/bin/env python3
# -*- coding:utf-8 -*-  
'多线程锁的问题'
__author__ = 'click'
__date__ = '2018/7/24 下午3:46'

import time, threading

'出现多线程数据混乱的问题:线程之间共享创建的全局变量' \
'多进程之间的变量:进程间相互独立的,不存在多进程操作同一变量' \
'多线程:共享同一变量,存在多线程对同一变量操作的情况'

#####################################
'多线程造成变量数据改变的原因' \
'原因是因为高级语言的一条语句在CPU执行时是若干条语句,即使一个简单的计算:'
'balance = balance + n'
'也分两步:'

'计算balance + n,存入临时变量中;'
'将临时变量的值赋给balance。'
'也就是可以看成:'

'x = balance + n'
'balance = x' \
    ####################################
'使用线程锁,对操作变量的方法进行加锁,保证变量值发生改变时只有一个线程对其操作。单线程的模式'

balance = 0

# 初始化一个锁
# 1. lock = threading.Lock()


def change_it(n):
    global balance
    balance = balance + n
    balance = balance - n


def run_thread(n):
    for i in range(1000000):
        # 1.首先申请锁
        # lock.acquire()
        try:
            change_it(n)
        finally:
            # 使用try  finaly 保证执行完之后,释放锁
           # lock.release()


t1 = threading.Thread(target=run_thread, args=(4,))
t2 = threading.Thread(target=run_thread, args=(6,))

t1.start()
t2.start()
t1.join()
t2.join()
print('balance %s' % balance)

先把锁相关的代码注释掉。

运行结果:

balance 4

按照代码正常的逻辑应该是如下:

n=4情况:
banlance =0
banlance = banlance+4  ->= banlance = 0+4 = 4
banlance = banlance-4  ->= banlance = 4-4 = 0

n=6情况:
banlance = 0
banlance = banlance +6 ->= banlance = 0+6 = 6
banlance = banlance -6 ->= banlance = 6-6 = 0

最后执行的结果banlance应该是0

那为什么会是4 呢?

创建多线程时候,应该按照先相加后相减。但是由于线程的调度是由操作系统直接控制。当t1,t2执行时,会出现<font color = red>交替执行</font>的情况。这样最后banlance的值就不等于0。

这里面具体的原因是高级语言在执行一下代码时候,分为两部分执行,

banlance = banlance+n
1.计算banlance+n,并将值赋值给临时变量
2.将临时变量赋值给banlance

这样我们就清楚了,因为操作系统在执行代码时候分两步,当多线程执行时候,就会出现

t1
banlance = 0 
banlance = banlnace +4 ->= x = 0+4 = 4

t2
banlance = 0 
banlance = banlance +6 ->= Y = 0+6 = 6

最终
banlance = Y
 

当t1代码开始运行到banlance = X时候,banlance = 4。对于t2任务 banlance的数据已经是错的了。

综上,多线程导致数据出现错误的原因是,多个线程同时操作同一个变量,导致变量的值出现错误。

所以,我们要保证在t1在操作banlance的时候,其他的线程就不能操作banlance,其他的线程就要等待。只有当t1执行完毕,并释放了对banlance的锁,其他的线程才能进行操作banlance变量。

如何对一个变量进行加锁,

  • 初始化一个锁
    lock=threading.Lock()
  • 获取锁
    lock.acquire()
  • 将要执行的代码使用try...finaly处理,并在finaly中释放锁 lock.realease()

也就是放开上述代码中的1、2、3处代码。

运行代码结果为:

banlance = 0

多线程

加锁

相关文章

  • GIL

    谈谈python的GIL、多线程、多进程 最近在看 Python 的多线程,经常我们会听到老手说:“python下...

  • Python多线程编程——多线程编程中的加锁机制

    如果大家对Python中的多线程编程不是很了解,推荐大家阅读之前的两篇文章:Python多线程编程——多线程基础介...

  • 5-线程(补充)

    Python多线程原理与实战 目的: (1)了解python线程执行原理 (2)掌握多线程编程与线程同步 (3)了...

  • Python_提高

    GIL全局解释器锁 描述Python GIL的概念, 以及它对python多线程的影响?编写⼀个 多线程抓取⽹⻚的...

  • Python程序员都知道的入门知识の八

    目录【Python程序员都知道的入门知识】 1. 多线程threading、Queue Python的多线程由th...

  • Python多线程实现生产者消费者

    1. Python多线程介绍 Python提供了两个有关多线程的标准库,thread和threading。thre...

  • 多线程

    Python多线程原理与实战 目的: (1)了解python线程执行原理 (2)掌握多线程编程与线程同步 (3)了...

  • Python多线程(上)

    前言 说起Python的多线程,很多人都嗤之以鼻,说Python的多线程是假的多线程,没有用,或者说不好用,那本次...

  • Python 3中的多线程

    Python 3的多线程 Python 3的多线程模块threading在旧版_thread模块基础上进行了更高层...

  • Python 多线程抓取图片效率实验

    Python 多线程抓取图片效率实验 实验目的: 是学习python 多线程的工作原理,及通过抓取400张图片这种...

网友评论

      本文标题:Python多线程

      本文链接:https://www.haomeiwen.com/subject/tgivmftx.html