Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元

线程不能实现多并发 只能实现伪并发 每次工作 只能是一个线程完成 由于python解释器 原生是c  原生线程 底层都会有一把锁

直接调用线程

#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = 'Administrator'

import  threading
import  time

def sayhi(num): #定义每个线程要运行的函数
    print("running on number:%s" %num)
    time.sleep(3)

if __name__ == '__main__':
    t1 = threading.Thread(target=sayhi,args=(1,))
    t2 = threading.Thread(target=sayhi,args=(1,))

    t1.start()    #启动线程
    t2.start()    #启动另一个线程

    print(t1.getName()) #获取线程名
    print(t2.getName())

如果需要开启10个线程呢 如何做 for循环

#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = 'Administrator'
import  threading
import  time
def sayhi(num): #定义每个线程要运行的函数
    print("running on number:%s" %num)
    time.sleep(3)

if __name__ == '__main__':
    for i in range(10):
        t = threading.Thread(target=sayhi,args=(i,))
        t.start()

继承调用

#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = 'Administrator'

import socketserver
import threading
import time

class Mythread(threading.Thread):
    def __init__(self,num):
        threading.Thread.__init__(self)
        self.num = num

    def run(self):  #定义每个线程要运行的函数
        print("running on number:%s" %self.num)
        time.sleep(3)

if __name__ == '__main__':
    t1 = Mythread(1)
    t2 = Mythread(2)
    t1.start()
    t2.start()

更多方法:

    • start            线程准备就绪,等待CPU调度
    • setName      为线程设置名称
    • getName      获取线程名称
    • setDaemon   设置为后台线程或前台线程(默认)
                         如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,均停止
                          如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止
    • join              逐个执行每个线程,执行完毕后继续往下执行,该方法使得多线程变得无意义
    • run              线程被cpu调度后自动执行线程对象的run方法

Join & Daemon

#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = 'Administrator'
import time
import threading

def run(n):
    print('[%s]------running----\n' % n)
    time.sleep(2)
    print('--done--')
def main():
    for i in range(5):
        t = threading.Thread(target=run,args=[i,])
        #time.sleep(1)
        t.start()
        #t.join(1)
        print('starting thread', t.getName())

m = threading.Thread(target=main,args=[])
#m.setDaemon(True) #将主线程设置为Daemon线程,它退出时,其它子线程会同时退出,不管是否执行完任务
m.start()
#m.join(timeout=10)
print("---main thread done----")

线程锁

一个进程下可以起到多个进程,多个线程共享父进程的内存空间,也意味着每个线程可以访问同一份数据,此时,如果2个线程同时

要修改一份数据,会出现什么状况?

由于线程之间是进行随机调度,并且每个线程可能只执行N条执行后,CPU接着执行其它线程。所以出现以下问题

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import threading
import time

gl_num = 0

def show(arg):
    global gl_num
    time.sleep(1)
    gl_num +=1
    print gl_num

for i in range(10):
    t = threading.Thread(target=show, args=(i,))
    t.start()

print 'main thread stop'

未使用锁

加锁后

#!/usr/bin/env python
#coding:utf-8

import threading
import time

gl_num = 0

lock = threading.RLock()

def Func():
    lock.acquire()
    global gl_num
    gl_num +=1
    time.sleep(1)
    print gl_num
    lock.release()

for i in range(10):
    t = threading.Thread(target=Func)
    t.start()

加锁后

import time
import threading

def addNum():
    global num #在每个线程中都获取这个全局变量
    print('--get num:',num )
    time.sleep(1)
    num  -=1 #对此公共变量进行-1操作

num = 100  #设定一个共享变量
thread_list = []
for i in range(100):
    t = threading.Thread(target=addNum)
    t.start()
    thread_list.append(t)

for t in thread_list: #等待所有线程执行完毕
    t.join()

print('final num:', num )

未加锁

import time
import threading

def addNum():
    global num #在每个线程中都获取这个全局变量
    print('--get num:',num )
    time.sleep(1)
    lock.acquire() #修改数据前加锁
    num  -=1 #对此公共变量进行-1操作
    lock.release() #修改后释放

num = 100  #设定一个共享变量
thread_list = []
lock = threading.Lock() #生成全局锁
for i in range(100):
    t = threading.Thread(target=addNum)
    t.start()
    thread_list.append(t)

for t in thread_list: #等待所有线程执行完毕
    t.join()

print('final num:', num )

加锁后

正常来讲,这个num结果应该是0, 但在python 2.7上多运行几次,会发现,最后打印出来的num结果不总是0,为什么每次运行的结果不一样呢? 哈,很简单,假设你有A,B两个线程,此时都 要对num 进行减1操作, 由于2个线程是并发同时运行的,所以2个线程很有可能同时拿走了num=100这个初始变量交给cpu去运算,当A线程去处完的结果是99,但此时B线程运算完的结果也是99,两个线程同时CPU运算的结果再赋值给num变量后,结果就都是99。那怎么办呢? 很简单,每个线程在要修改公共数据时,为了避免自己在还没改完的时候别人也来修改此数据,可以给这个数据加一把锁, 这样其它线程想修改此数据时就必须等待你修改完毕并把锁释放掉后才能再访问此数据。

*注:不要在3.x上运行,不知为什么,3.x上的结果总是正确的,可能是自动加了锁

线程锁跟远程线程底层锁GIL是没有关联的  两个线程要同时更改一个共享数据很难保证数据的一致性,所以要加上线程锁 等1个线程运行完 在释放锁 保证数据的一致性

Queue队列

class queue.Queue(maxsize=0) #先入先出
class queue.LifoQueue(maxsize=0) #last in fisrt out 
class queue.PriorityQueue(maxsize=0) #存储数据时可设置优先级的队列

简单的语法命令

import queue

q = queue.Queue(maxsize=3) #最大3个
#q.get()   #阻塞
#q.get(timeout=3) #3秒后 报异常 queue.Empty
q.get_nowait() #报异常 于q.get(timeout=3)是一样的效果

加一点数据 put

import queue

q = queue.Queue(maxsize=3) #最大3个
q.put([1,2,3])     #存放一个列表
#q.get()   #阻塞
#q.get(timeout=3) #3秒后 报异常 queue.Empty
#q.get_nowait() #报异常 于q.get(timeout=3)是一样的效果
data = q.get_nowait()
print(data,type(data))

判断最大值是否满了

import queue

q = queue.Queue(maxsize=3) #最大3个
q.put([1,2,3])
q.put(1)
q.put(2)
q.put(3,timeout=2)
data = q.get_nowait() #释放一个
q.put(4)
#print(data,type(data))
print(q.full())  #q.full()判断是否满

先入后出

q = queue.LifoQueue(maxsize=30)
q.put([1,2,3])
q.put(1)
q.put(3)
print(q.get())

#获取的值为
3

优选级

import queue

q = queue.PriorityQueue(maxsize=30)
q.put((7,[1,2,3]))
q.put((6,1))
q.put((5,3))
print(q.get())

#获取的值为
(5, 3)

生产者消费者

#!/usr/bin/env python
#_*_ coding:utf8 _*_
__author__ = 'Administrator'
import threading,queue
import time

def consumer(n):
    while True:
        print("consumer [%s] get task: %s" % (n,q.get()))
        time.sleep(1)
        q.task_done()

def producer(n):
    count = 1
    while True:
            time.sleep(0.5)
        #for i in range(2):
            print("prodcer [%s] produced a new task : %s" %(n,count))
            q.put(count)
            count += 1
            q.join()
            print("all taks has been cosumed by consumers........")

l = threading.Lock

#相当于服务员
q = queue.Queue()
#消费者
c1 = threading.Thread(target=consumer,args=[1,])
c2 = threading.Thread(target=consumer,args=[2,])
c3 = threading.Thread(target=consumer,args=[3,])

#生产者
p = threading.Thread(target=producer,args=["alex",])
p2 = threading.Thread(target=producer,args=["yiyezi",])
p3 = threading.Thread(target=producer,args=["haha",])

#启动
c1.start()
c2.start()
c3.start()
p.start()
p2.start()
p3.start()

Python 线程,进程的更多相关文章

  1. python 线程 进程

    1.进程与线程优.缺点的比较总言:使用进程和线程的目的,提高执行效率. 进程: 优点:能利用机器的多核性能,同时进行多个操作. 缺点:需要耗费资源,重新开辟内存空间,耗内存. 线程: 优点:共享内存( ...

  2. python 线程 进程 协程 学习

    转载自大神博客:http://www.cnblogs.com/aylin/p/5601969.html 仅供学习使用···· python 线程与进程简介 进程与线程的历史 我们都知道计算机是由硬件和 ...

  3. python线程进程

    多道技术: 多道程序设计技术 所谓多道程序设计技术,就是指允许多个程序同时进入内存并运行.即同时把多个程序放入内存,并允许它们交替在CPU中运行,它们共享系统中的各种硬.软件资源.当一道程序因I/O请 ...

  4. Python 线程&进程与协程

    Python 的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承.Py ...

  5. python 线程进程

      一 线程的2种调用方式 直接调用 实例1: import threading import time def sayhi(num): #定义每个线程要运行的函数 print("runni ...

  6. python线程,进程,队列和缓存

    一.线程 threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. 创建线程的两种方式1.threading.Thread import threading def f1(arg): ...

  7. python 线程,进程28原则

    基于函数实现 from threading import Thread def fun(data, *args, **kwargs): """ :param data: ...

  8. python 线程/进程模块

    线程的基本使用: import threading # ###################### 1.线程的基本使用 def func(arg): print(arg) t = threading ...

  9. python 线程 进程 标识

    s = '%s%s%s%s%s%s%s%s' % ( time.strftime('%Y%m%d %H:%M:%S', time.localtime(time.time())), ' os.getpp ...

  10. python 线程(一)理论部分

    Python线程 进程有很多优点,它提供了多道编程,可以提高计算机CPU的利用率.既然进程这么优秀,为什么还要线程呢?其实,仔细观察就会发现进程还是有很多缺陷的. 主要体现在一下几个方面: 进程只能在 ...

随机推荐

  1. 第六十三节,html表格元素

    html表格元素 学习要点:     1.表格元素总汇     2.构建表格解析     本章主要探讨HTML5中表格元素的用法.表格的主要用途是以网格的形式显示二维数据. 一.表格元素总汇     ...

  2. Node.js:包

    概要:本篇博客主要介绍了node.js中的包 包是在模块基础上更深一步的抽象,Node.js的包类似于C/C++的库函数或者Java/.Net的类库.它将某个独立的功能封装起来,用于发布.更新.依赖管 ...

  3. C# Monads的实现(二)

    再谈continuation monad 上一篇中我们已经介绍了continuation monad,但是这个monad与Identity,Maybe,IEnumerable monads稍微难于理解 ...

  4. Objetive-C initialize研究

    initialize执行时机           在向一个类执行实例方法或者类方法(除了initialize和load方法之外)的时候,触发initialize方法,因此如果一个类你没有使用的时候,是 ...

  5. Lucene基础(1)

    下一篇: Lucene基础(2) 一.Lucene介绍 http://www.kailing.pub/index/columns/colid/16.html Documentation:http:// ...

  6. MySQL事务内幕与ACID

    MySQL的事务实现严格遵循ACID特性,即原子性(atomicity),一致性(consistency),隔离性(isolation),持久性(durability).为了避免一上来就陷入对ACID ...

  7. Chapter 16_3 多重继承

    在Lua中进行面向对象编程时有几种方法,上一小结介绍了一种使用__index元方法的做法. 下面要介绍另一种方法,可以在Lua中实现多继承. 关键一点,在于用函数作为__index元字段. 多重继承意 ...

  8. sharepoint2010配置个人网站的offical方法 来自Jetluning的专栏

    Configuring My Site in SharePoint 201   SharePoint My Sites are commonly referred to as “Facebook fo ...

  9. id和instancetype的异同

    相同点: 都可以作为方法返回值类型 在initWithName:方法中是一样的,例如: - (id)initWithName:(NSString *)name; - (instancetype)ini ...

  10. ubuntu下安装UltraEdit

    在windows下常年使用UltraEdit来查看log,现在突然切换到ubuntu下,系统自带的Text Editor相当不适应:只有自己安装了. 首先,需要下载安装包,可以去:http://www ...