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. USACO 1.5 Prime Palindromes

    Prime Palindromes The number 151 is a prime palindrome because it is both a prime number and a palin ...

  2. Counting Stars

    Counting Stars 题目链接:http://acm.xidian.edu.cn/problem.php?id=1177 离线+一维树状数组 一眼扫过去:平面区间求和,1e6的数据范围,这要h ...

  3. C#获取网页内容 (WebClient、WebBrowser和HttpWebRequest/HttpWebResponse)

    获取网页数据有很多种方式.在这里主要讲述通过WebClient.WebBrowser和HttpWebRequest/HttpWebResponse三种方式获取网页内容. 这里获取的是包括网页的所有信息 ...

  4. Jira 6.0.3安装破解汉化

    前段时间和上海的朋友交流了下,他们公司使用JIRA管理项目.回来整理了下感觉很不错. http://www.unlimax.com/jira.html工作中总是有各种事务要去处理,而这些事务不仅仅是代 ...

  5. Sass与Compress实战:第六章

    概要:介绍Compass如何让你从本地开发原型轻松转移到正产环境的网址或Web应用中. 本章内容: ● CSS精灵的历史和基本原则 ● Compass混合器让精灵自动化 ● 自定义精灵图片和CSS输出 ...

  6. 【Sort】希尔排序

    希尔排序(ShellSort),缩小增量排序,使用希尔增量时最坏运行时间O(n^2),不同的增量会对运行时间产生显著影响. void shellsort(int *nums,int n) { int ...

  7. 100+ 值得收藏的 Web 开发资源

    原文 http://mp.weixin.qq.com/s?__biz=MjM5OTEzMzQwMA==&mid=2651667152&idx=2&sn=1dd7a77a2eff ...

  8. hdu_5879_Cure(打表)

    题目链接:hdu_5879_Cure 题意: 给你一个n,让你计算1/k2的和,k从1到n. 题解: 因为只保留5位小数,所以打个100W的表,比这个数大的直接输出最后一位就行了 #include&l ...

  9. hadoop---wordcount命令

    [zznu@master file]$ hadoop jar ~/hadoop-2.5.2/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.5.2 ...

  10. Arch最小化安装LXDE桌面环境

    安装最小化的LXDE桌面环境: pacman -S lxde-common 安装LXDE Session: pacman -S lxsession 不安装这个没法登录进桌面环境 安装LXDE面板: p ...