Python多线程

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

多线程

加锁

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • 一文读懂Python多线程 1、线程和进程 计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运...
    星丶雲阅读 1,442评论 0 4
  • Python 多线程 多线程类似于同时执行多个不同程序,多线程运行有如下优点: 使用线程可以把占据长时间的程序...
    今早上阅读 345评论 0 0
  • 线程和进程 计算机,用于计算的机器。计算机的核心是CPU,在现在多核心的电脑很常见了。为了充分利用cpu核心做计算...
    人世间阅读 24,322评论 3 85
  • 染发 文/雄关漫道 年刚过,故事都在发上 窗外的法桐 摇晃着昨天 小妹很青春 一剪一剪地 我的沧桑,便落了一地 闭...
    闫殿才阅读 486评论 9 46
  • (1)规则变量以$符号开头,其后是变量的名称变量名称只能包含字母,数字和下划线变量名称必须以字母或下划线开头变量名...
    何幻阅读 520评论 0 3