多线程
 
基本实现:
第一种,函数方式
# -*- coding:utf-8 -*-
import thread
import time
 
 
def print_time(threadName, delay):
    count = 0
    while count < 5:
        time.sleep(delay)
        count += 1
        print '%s : %s' % (threadName, time.ctime(time.time()))
 
 
try:
    thread.start_new_thread(print_time, ("Thread-1", 2,))
    thread.start_new_thread(print_time, ("Thread-2", 4,))
except:
    print "Error!Unable to start thread."
 
while 1:
    pass
 
第二种,继承父类
# -*- coding:utf-8 -*-
import threading
import time
 
 
class MyThread(threading.Thread):
    def __init__(self, thread_id, name, counter):
        threading.Thread.__init__(self)
        self.thread_id = thread_id
        self.name = name
        self.counter = counter
 
    def run(self):
        print "Starting:" + self.name
        print_time(self.name, self.counter, 5)
        print "Exiting:" + self.name
 
 
def print_time(thread_name, delay, counter):
    while counter:
        time.sleep(delay)
        print '%s : %s' % (thread_name, time.ctime(time.time()))
        counter -= 1
 
 
thread1 = MyThread(1, "Thread-1", 1)
thread2 = MyThread(2, "Thread-2", 2)
 
thread1.start()
thread2.start()
 
线程同步的问题解决:锁
这里第一个线程执行的时候,第二个线程是等待状态的
# -*- coding:utf-8 -*-
import threading
import time
 
threadLock = threading.Lock()
threads = []
 
 
class MyThread(threading.Thread):
    def __init__(self, thread_id, name, counter):
        threading.Thread.__init__(self)
        self.thread_id = thread_id
        self.name = name
        self.counter = counter
 
    def run(self):
        print "Starting:" + self.name
        threadLock.acquire()
        print_time(self.name, self.counter, 5)
        print "Exiting:" + self.name
        threadLock.release()
 
 
def print_time(thread_name, delay, counter):
    while counter:
        time.sleep(delay)
        print '%s : %s' % (thread_name, time.ctime(time.time()))
        counter -= 1
 
 
thread1 = MyThread(1, "Thread-1", 1)
thread2 = MyThread(2, "Thread2", 2)
 
thread1.start()
thread2.start()
 
threads.append(thread1)
threads.append(thread2)
 
for thread in threads:
    thread.join()
 
线程优先级队列:
虽然开启了多个线程,不过打印顺序一定是:one按顺序到five
# -*- coding:utf-8 -*-
import threading
import time
import Queue
 
exit_flag = 0
queue_lock = threading.Lock()
work_queue = Queue.Queue(10)
thread_list = ["Thread-1", "Thread-2", "Thread-3"]
name_list = ["one", "two", "three", "four", "five"]
threads = []
thread_id = 1
 
 
class MyThread(threading.Thread):
    def __init__(self, thread__id, name, queue):
        threading.Thread.__init__(self)
        self.thread__id = thread__id
        self.name = name
        self.queue = queue
 
    def run(self):
        print "Starting:" + self.name
        process_data(self.name, self.queue)
        print "Exiting:" + self.name
 
 
def process_data(thread_name, queue):
    while not exit_flag:
        queue_lock.acquire()
        if not work_queue.empty():
            data = queue.get()
            queue_lock.release()
            print "%s processing %s" % (thread_name, data)
        else:
            queue_lock.release()
        time.sleep(2)
 
 
for t in thread_list:
    thread = MyThread(thread_id, t, work_queue)
    thread.start()
    threads.append(thread)
    thread_id += 1
 
queue_lock.acquire()
for word in name_list:
    work_queue.put(word)
queue_lock.release()
 
while not work_queue.empty():
    pass
 
exit_flag = 1
 
for t in threads:
    t.join()
 
这里的join函数重点解释下:
join的原理就是依次检验线程池中的线程是否结束,没有结束就阻塞主线程直到其他线程结束,如果结束则跳转执行下一个线程的join函数
 
接下来看看多线程实际的案例:
多线程访问网站
# -*- coding:utf-8 -*-
import urllib2
import time
from threading import Thread
 
 
class GetUrlThread(Thread):
    def __init__(self, url):
        Thread.__init__(self)
        self.url = url
 
    def run(self):
        response = urllib2.urlopen(self.url)
        print self.url, response.getcode()
 
 
def get_responses():
    urls = [
        'https://www.baidu.com',
        'https://www.taobao.com',
        'https://www.cnblogs.com',
        'https://github.com',
        'https://www.jd.com'
    ]
    start = time.time()
    threads = []
    for url in urls:
        thread = GetUrlThread(url)
        threads.append(thread)
        thread.start()
 
    for thread in threads:
        thread.join()
 
    print "Time: % s" % (time.time() - start)
 
 
get_responses()
 
如果多个线程访问同一个变量,容易出问题,比如下面:
有可能最后的实际值并不是50
# -*- coding:utf-8 -*-
from threading import Thread
 
some_var = 0
 
 
class IncrementThread(Thread):
    def run(self):
        global some_var
        read_value = some_var
        print "线程%s中的some_var是%d" % (self.name, read_value)
        some_var = read_value + 1
        print "线程%s中的some_var增加后变成%d" % (self.name, some_var)
 
 
def use_increment_thread():
    threads = []
    for i in range(50):
        thread = IncrementThread()
        threads.append(thread)
        thread.start()
 
    for thread in threads:
        thread.join()
 
    print "在50次运算后some_var应该变成50"
    print "在50次运算后some_var实际值为:%d" % (some_var,)
 
 
use_increment_thread()
 
解决办法,加入一个锁:
这种情况,最后的实际值一定是50
# -*- coding:utf-8 -*-
from threading import Thread, Lock
 
lock = Lock()
some_var = 0
 
 
class IncrementThread(Thread):
    def run(self):
        global some_var
        lock.acquire()
        read_value = some_var
        print "线程%s中的some_var是%d" % (self.name, read_value)
        some_var = read_value + 1
        print "线程%s中的some_var增加后变成%d" % (self.name, some_var)
        lock.release()
 
 
def use_increment_thread():
    threads = []
    for i in range(50):
        thread = IncrementThread()
        threads.append(thread)
        thread.start()
 
    for thread in threads:
        thread.join()
 
    print "在50次运算后some_var应该变成50"
    print "在50次运算后some_var实际值为:%d" % (some_var,)
 
 
use_increment_thread()
 
另一个锁的案例:
不加锁容易出事
# -*- coding:utf-8 -*-
from threading import Thread
import time
 
 
class CreateListThread(Thread):
    def __init__(self):
        self.entries = []
        Thread.__init__(self)
 
    def run(self):
        self.entries = []
        for i in range(10):
            time.sleep(1)
            self.entries.append(i)
        print self.entries
 
 
def use_create_list_thread():
    for i in range(3):
        t = CreateListThread()
        t.start()
 
 
use_create_list_thread()
结果:
[[[000, , , 111, , , 222, , , 333, , , 444, , , 555, , , 666, , , 777, , , 888, , , 999]]]
 
给他加上锁:
# -*- coding:utf-8 -*-
from threading import Thread, Lock
import time
 
lock = Lock()
 
 
class CreateListThread(Thread):
    def __init__(self):
        self.entries = []
        Thread.__init__(self)
 
    def run(self):
        self.entries = []
        for i in range(10):
            time.sleep(1)
            self.entries.append(i)
        lock.acquire()
        print self.entries
        lock.release()
 
 
def use_create_list_thread():
    for i in range(3):
        t = CreateListThread()
        t.start()
 
 
use_create_list_thread()
结果:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Python多线程使用和注意事项的更多相关文章

  1. python多线程与_thread模块

    进程与线程 1.进程:计算机程序只是存储在磁盘中的可执行二进制(或其他类型)的文件.只有把他们加载到内存中并被操作系统调用,才具有其生命周期.进程则是一个执行中的程序.每个进程都拥有自己的地址空间,内 ...

  2. python多线程学习记录

    1.多线程的创建 import threading t = t.theading.Thread(target, args--) t.SetDeamon(True)//设置为守护进程 t.start() ...

  3. python多线程编程

    Python多线程编程中常用方法: 1.join()方法:如果一个线程或者在函数执行的过程中调用另一个线程,并且希望待其完成操作后才能执行,那么在调用线程的时就可以使用被调线程的join方法join( ...

  4. Python 多线程教程:并发与并行

    转载于: https://my.oschina.net/leejun2005/blog/398826 在批评Python的讨论中,常常说起Python多线程是多么的难用.还有人对 global int ...

  5. python多线程

    python多线程有两种用法,一种是在函数中使用,一种是放在类中使用 1.在函数中使用 定义空的线程列表 threads=[] 创建线程 t=threading.Thread(target=函数名,a ...

  6. python 多线程就这么简单(转)

    多线程和多进程是什么自行google补脑 对于python 多线程的理解,我花了很长时间,搜索的大部份文章都不够通俗易懂.所以,这里力图用简单的例子,让你对多线程有个初步的认识. 单线程 在好些年前的 ...

  7. python 多线程就这么简单(续)

    之前讲了多线程的一篇博客,感觉讲的意犹未尽,其实,多线程非常有意思.因为我们在使用电脑的过程中无时无刻都在多进程和多线程.我们可以接着之前的例子继续讲.请先看我的上一篇博客. python 多线程就这 ...

  8. python多线程监控指定目录

    import win32file import tempfile import threading import win32con import os dirs=["C:\\WINDOWS\ ...

  9. python多线程ssh爆破

    python多线程ssh爆破 Python 0x01.About 爆弱口令时候写的一个python小脚本,主要功能是实现使用字典多线程爆破ssh,支持ip表导入,字典数据导入. 主要使用到的是pyth ...

随机推荐

  1. Springmvc中@RequestMapping 属性用法归纳

    简介: @RequestMapping RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上.用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径. RequestM ...

  2. 使用QML绘制界面

    1 使用QML设计登录界面 https://www.cnblogs.com/bhlsheji/p/5324871.html 2 使用QML实现下拉列表框  https://blog.csdn.net/ ...

  3. 前端面试之vue相关的面试题

    hello,你们的小可爱,皮皮聪又来发表感想了. 首先简单概括下会遇到的问题: 1.vuex作用 ①vuex是一个状态管理的插件,可以解决不同组件之间的数据共享和数据持久化. ②vue中的多个组件之间 ...

  4. HTML与盒模型

    EC前端 - HTML教程 HTML与盒模型 HTML结构 <!doctype html> <html> <head> <meta charset=" ...

  5. 关于git的一些命令

    git命令 1.git init 初始化仓库 2.git status 查看当前状态 3.git add -A(提交所有的) 提交本地文件到缓存区 4.git commit -m"提交信息& ...

  6. Swift 加载 xib 崩溃问题

    新版本用 Swift开发 遇到的坑 解决方法

  7. 招聘ETL开发工程师

    上班地点徐汇 本科以上学历 3年以上ETL开发经验熟悉Oracle数据库,精通PL  SQL开发与优化,熟悉Vertica或者GreenPlum库优先 熟悉数据库性能优化,有海量数据处理经验优先 自荐 ...

  8. cosfuture logs

    1,RESTClient用于调试接口的插件 2, PHP_AUTH_USER如何发送 $a = base64_encode("username:password"); 注意中间是冒 ...

  9. 初学者必看的文章:在VM12中安装 RedHat RHEL7.2  系统的详细步骤:看我如何操纵RHEL系统

    一.开始安装 1)新建虚拟机 RHEL7.2 2)成功引导系统--开机出现此画面 Install Red Hat EnterpriseLinux 7.2  安装RHLE7.2 操作系统 Test th ...

  10. Paper | 多任务学习的鼻祖

    目录 1. MTL的定义 2. MTL的机制 2.1. Representation Bias 2.2. Uncorrelated Tasks May Help? 3. MTL的用途 3.1. Usi ...