码迷,mamicode.com
首页 > 编程语言 > 详细

多线程-theading

时间:2018-04-17 21:19:22      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:http   range   app   全局变量   work   strong   append   __name__   elf   

1.使用threading模块

#coding=utf-8
import threading
import time
def saySorry():
    print("亲爱的,我错了,我能吃饭了吗?")
    time.sleep(1)
if __name__ == "__main__":
    for i in range(5):
        t = threading.Thread(target=saySorry)
        t.start() #启动线程,即让线程开始执?

说明
  1. 可以明显看出使?了多线程并发的操作,花费时间要短很多
  2. 创建好的线程,需要调? start() ?法来启动

2.主线程会等待所有的?线程结束后才结束

#coding=utf-8
import threading
from time import sleep,ctime
def sing():
    for i in range(3):
        print("正在唱歌...%d"%i)
        sleep(1)
def dance():
    for i in range(3):
       print("正在跳舞...%d"%i)
        sleep(1)
if __name__ == __main__:
    print(---开始---:%s%ctime())
    t1 = threading.Thread(target=sing)
    t2 = threading.Thread(target=dance)
    t1.start()
    t2.start()
    #sleep(5) # 屏蔽此?代码,试试看,程序是否会??结束?
    print(---结束---:%s%ctime())

3.查看线程数量

    while True:
        length = len(threading.enumerate())
        print(当前运?的线程数为:%d%length)
        if length<=1:
            break

4.run()方法写

#coding=utf-8
import threading
import time
class MyThread(threading.Thread):
    def run(self):
        for i in range(3):
            time.sleep(1)
            msg = "I‘m "+self.name+ @ +str(i) #name属性中保存的是当前线程的名字
            print(msg)
if __name__ == __main__:
    t = MyThread()
    t.start()

说明
  python的threading.Thread类有?个run?法,?于定义线程的功能函
  数,可以在??的线程类中覆盖该?法。?创建??的线程实例后,通
  过Thread类的start?法,可以启动该线程,交给python虚拟机进?调
  度,当该线程获得执?的机会时,就会调?run?法执?线程。

5.线程的执行顺序

#coding=utf-8
import threading
import time
class MyThread(threading.Thread):
    def run(self):
       for i in range(3):
       time.sleep(1)
        msg = "I‘m "+self.name+ @ +str(i)
        print(msg)
def test():
    for i in range(5):
        t = MyThread()
        t.start()
if __name__ == __main__:
    test()

说明
  从代码和执?结果我们可以看出,多线程程序的执?顺序是不确定的。当执
  ?到sleep语句时,线程将被阻塞(Blocked),到sleep结束后,线程进?就
  绪(Runnable)状态,等待调度。?线程调度将??选择?个线程执?。上
  ?的代码中只能保证每个线程都运?完整个run函数,但是线程的启动顺序、
  run函数中每次循环的执?顺序都不能确定。

6.线程的几种状态

技术分享图片

7.多线程-共享全局变量

from threading import Thread
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)
print("---线程创建之前g_num is %d---"%g_num)
t1 = Thread(target=work1)
t1.start()
#延时?会,保证t1线程中的事情做完
time.sleep(1)
t2 = Thread(target=work2)
t2.start()

8.列表当中参数传递到线程中

from threading import Thread
import time
def work1(nums):
    nums.append(44)
    print("----in work1---",nums)
def work2(nums):
    #延时?会,保证t1线程中的事情做完
    time.sleep(1)
    print("----in work2---",nums)
g_nums = [11,22,33]
t1 = Thread(target=work1, args=(g_nums,))
t1.start()
t2 = Thread(target=work2, args=(g_nums,))
t2.start()

运?结果:
----in work1--- [11, 22, 33, 44]
----in work2--- [11, 22, 33, 44]

    缺点就是,线程是对全局变量随意遂改可能造成多线程之间对全局变量
  的混乱(即线程?安全)

9.进程 VS 线程 

  功能
    ·进程,能够完成多任务,?如 在?台电脑上能够同时运?多个QQ
    ·线程,能够完成多任务,?如 ?个QQ中的多个聊天窗? 

  定义的不同
    ·进程是系统进?资源分配和调度的?个独?单位.
    ·线程是进程的?个实体,是CPU调度和分派的基本单位,它是?进程更?的
     能独?运?的基本单位.线程??基本上不拥有系统资源,只拥有?点在运
     ?中必不可少的资源(如程序计数器,?组寄存器和栈),但是它可与同属?
     个进程的其他的线程共享进程所拥有的全部资源.

  区别
    ·?个程序?少有?个进程,?个进程?少有?个线程.
    ·线程的划分尺度?于进程(资源?进程少),使得多线程程序的并发性?。
    ·进程在执?过程中拥有独?的内存单元,?多个线程共享内存,从?极
     ?地提?了程序的运?效率
    ·线线程不能够独?执?,必须依存在进程中

  优缺点
    线程和进程在使?上各有优缺点:线程执?开销?,但不利于资源的管理和
  保护;?进程正相反。

10.互斥锁

    当多个线程?乎同时修改某?个共享数据的时候,需要进?同步控制
    线程同步能够保证多个线程安全访问竞争资源,最简单的同步机制是引?互
  斥锁。
    互斥锁为资源引??个状态:锁定/?锁定。

threading模块中定义了Lock类,可以?便的处理锁定:

#创建锁
mutex = threading.Lock()
#锁定
mutex.acquire([blocking])
#释放
mutex.release()

  其中,锁定?法acquire可以有?个blocking参数。
    ·如果设定blocking为True,则当前线程会堵塞,直到获取到这个锁为?
    (如果没有指定,那么默认为True)
    ·如果设定blocking为False,则当前线程不会堵塞

from threading import Thread, Lock
import time
g_num = 0
def test1():
    global g_num
    for i in range(1000000):
        #True表示堵塞 即如果这个锁在上锁之前已经被上锁了,那么这个线程会在这??直等待到解锁为?
        #False表示?堵塞,即不管本次调?能够成功上锁,都不会卡在这,?是继续执?下?的代码
        mutexFlag = mutex.acquire(True)
       if mutexFlag:
            g_num += 1
            mutex.release()
    print("---test1---g_num=%d"%g_num)
def test2():
    global g_num
    for i in range(1000000):
        mutexFlag = mutex.acquire(True) #True表示堵塞
        if mutexFlag:
            g_num += 1
           mutex.release()
        print("---test2---g_num=%d"%g_num)
#创建?个互斥锁
#这个所默认是未上锁的状态
mutex = Lock()
p1 = Thread(target=test1)
p1.start()
p2 = Thread(target=test2)
p2.start()
print("---g_num=%d---"%g_num)

11.同步应用--多个线程有序执?

from threading import Thread,Lock
from time import sleep
class Task1(Thread):
    def run(self):
        while True:
            if lock1.acquire():
                print("------Task 1 -----")
                sleep(0.5)
                lock2.release()
class Task2(Thread):
    def run(self):
        while True:
            if lock2.acquire():
                print("------Task 2 -----")
                sleep(0.5)
                lock3.release()
class Task3(Thread):
    def run(self):
        while True:
            if lock3.acquire():
                print("------Task 3 -----")
                sleep(0.5)
                lock1.release()
#使?Lock创建出的锁默认没有“锁上”
lock1 = Lock()
#创建另外?把锁,并且“锁上”
lock2 = Lock()
lock2.acquire()
#创建另外?把锁,并且“锁上”
lock3 = Lock()
lock3.acquire()
t1 = Task1()
t2 = Task2()
t3 = Task3()
t1.start()
t2.start()
t3.start()

12.?产者与消费者模式

  队列:先进先出

  栈:先进后出

?产者与消费者模式可以用来解决写入,读取不同步问题

?产者消费者模式是通过?个容器来解决?产者和消费者的强耦合问题。?
产者和消费者彼此之间不直接通讯,?通过阻塞队列来进?通讯,所以?产
者?产完数据之后不?等待消费者处理,直接扔给阻塞队列,消费者不找?
产者要数据,?是直接从阻塞队列?取,阻塞队列就相当于?个缓冲区,平
衡了?产者和消费者的处理能?。
这个阻塞队列就是?来给?产者和消费者解耦的。纵观?多数设计模式,都
会找?个第三者出来进?解耦,

13.ThreadLocal

  ThreadLocal应运??,不?查找dict,ThreadLocal帮你?动做这件事:

import threading
# 创建全局ThreadLocal对象:
local_school = threading.local()
def process_student():
    # 获取当前线程关联的student:
    std = local_school.student
    print(Hello, %s (in %s) % (std, threading.current_thread().name))
def process_thread(name):
    # 绑定ThreadLocal的student:
    local_school.student = name
    process_student()
t1 = threading.Thread(target= process_thread, args=(dongGe,), name=
t2 = threading.Thread(target= process_thread, args=(?王,), name=
t1.start()
t2.start()
t1.join()
t2.join()

说明
  全局变量local_school就是?个ThreadLocal对象,每个Thread对它都可以读
  写student属性,但互不影响。你可以把local_school看成全局变量,但每个
  属性如local_school.student都是线程的局部变量,可以任意读写?互不?
  扰,也不?管理锁的问题,ThreadLocal内部会处理。
  可以理解为全局变量local_school是?个dict,不但可以?
  local_school.student,还可以绑定其他变量,如local_school.teacher等等。
  ThreadLocal最常?的地?就是为每个线程绑定?个数据库连接,HTTP请
  求,?户身份信息等,这样?个线程的所有调?到的处理函数都可以?常?
  便地访问这些资源。

多线程-theading

标签:http   range   app   全局变量   work   strong   append   __name__   elf   

原文地址:https://www.cnblogs.com/zhaopengyublogs/p/8870015.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!