当前位置:   article > 正文

Python threading Thread多线程的使用方法_threading.thread.__init__(self)

threading.thread.__init__(self)

Python threading Thread多线程的使用方法

参考资料:《Python 多线程》http://www.runoob.com/python/python-multithreading.html

目录

Python threading Thread多线程的使用方法

1.使用Threading模块创建线程

2.Thread线程同步

3.使用多线程读取图像并返回数据


1.使用Threading模块创建线程

使用Threading模块创建线程,直接从threading.Thread继承,然后重写__init__方法和run方法:

  1. #!/usr/bin/python
  2. # -*- coding: UTF-8 -*-
  3. import threading
  4. import time
  5. exitFlag = 0
  6. class myThread (threading.Thread): #继承父类threading.Thread
  7. def __init__(self, threadID, name, counter):
  8. threading.Thread.__init__(self)
  9. self.threadID = threadID
  10. self.name = name
  11. self.counter = counter
  12. def run(self): #把要执行的代码写到run函数里面 线程在创建后会直接运行run函数
  13. print "Starting " + self.name
  14. print_time(self.name, self.counter, 5)
  15. print "Exiting " + self.name
  16. def print_time(threadName, delay, counter):
  17. while counter:
  18. if exitFlag:
  19. (threading.Thread).exit()
  20. time.sleep(delay)
  21. print "%s: %s" % (threadName, time.ctime(time.time()))
  22. counter -= 1
  23. # 创建新线程
  24. thread1 = myThread(1, "Thread-1", 1)
  25. thread2 = myThread(2, "Thread-2", 2)
  26. # 开启线程
  27. thread1.start()
  28. thread2.start()
  29. print "Exiting Main Thread"

以上程序执行结果如下;

  1. Starting Thread-1
  2. Starting Thread-2
  3. Exiting Main Thread
  4. Thread-1: Thu Mar 21 09:10:03 2013
  5. Thread-1: Thu Mar 21 09:10:04 2013
  6. Thread-2: Thu Mar 21 09:10:04 2013
  7. Thread-1: Thu Mar 21 09:10:05 2013
  8. Thread-1: Thu Mar 21 09:10:06 2013
  9. Thread-2: Thu Mar 21 09:10:06 2013
  10. Thread-1: Thu Mar 21 09:10:07 2013
  11. Exiting Thread-1
  12. Thread-2: Thu Mar 21 09:10:08 2013
  13. Thread-2: Thu Mar 21 09:10:10 2013
  14. Thread-2: Thu Mar 21 09:10:12 2013
  15. Exiting Thread-2

2.Thread线程同步

如果多个线程共同对某个数据修改,则可能出现不可预料的结果,为了保证数据的正确性,需要对多个线程进行同步。使用Thread对象的Lock和Rlock可以实现简单的线程同步,这两个对象都有acquire方法和release方法,对于那些需要每次只允许一个线程操作的数据,可以将其操作放到acquire和release方法之间。

多线程的优势在于可以同时运行多个任务(至少感觉起来是这样)。但是当线程需要共享数据时,可能存在数据不同步的问题。

考虑这样一种情况:一个列表里所有元素都是0,线程"set"从后向前把所有元素改成1,而线程"print"负责从前往后读取列表并打印。

那么,可能线程"set"开始改的时候,线程"print"便来打印列表了,输出就成了一半0一半1,这就是数据的不同步。为了避免这种情况,引入了锁的概念。

锁有两种状态——锁定和未锁定。每当一个线程比如"set"要访问共享数据时,必须先获得锁定;如果已经有别的线程比如"print"获得锁定了,那么就让线程"set"暂停,也就是同步阻塞;等到线程"print"访问完毕,释放锁以后,再让线程"set"继续。

经过这样的处理,打印列表时要么全部输出0,要么全部输出1,不会再出现一半0一半1的尴尬场面。

  1. # -*-coding: utf-8 -*-
  2. """
  3. @Project: cluster
  4. @File : thread_processing.py
  5. @Author : panjq
  6. @E-mail : pan_jinquan@163.com
  7. @Date : 2019-03-13 13:43:49
  8. """
  9. # !/usr/bin/python
  10. # -*- coding: UTF-8 -*-
  11. # !/usr/bin/python
  12. # -*- coding: UTF-8 -*-
  13. import threading
  14. import time
  15. class myThread(threading.Thread):
  16. def __init__(self, threadID, name, counter):
  17. threading.Thread.__init__(self)
  18. self.threadID = threadID
  19. self.name = name
  20. self.counter = counter
  21. def run(self):
  22. print("Starting " + self.name)
  23. # 获得锁,成功获得锁定后返回True
  24. # 可选的timeout参数不填时将一直阻塞直到获得锁定
  25. # 否则超时后将返回False
  26. threadLock.acquire()
  27. self.print_time(self.name, self.counter, 3)
  28. # 释放锁
  29. threadLock.release()
  30. def print_time(self,threadName, delay, counter):
  31. while counter:
  32. time.sleep(delay)
  33. print("%s: %s" % (threadName, time.ctime(time.time())))
  34. counter -= 1
  35. threadLock = threading.Lock()
  36. threads = []
  37. # 创建新线程
  38. thread1 = myThread(1, "Thread-1", 1)
  39. thread2 = myThread(2, "Thread-2", 2)
  40. # 开启新线程
  41. thread1.start()
  42. thread2.start()
  43. # 添加线程到线程列表
  44. threads.append(thread1)
  45. threads.append(thread2)
  46. # 等待所有线程完成
  47. for t in threads:
  48. t.join()
  49. print("Exiting Main Thread")

3.使用多线程读取图像并返回数据

下面是使用多线程的方法,实现读取图片的方法,注意这里增加了一个函数get_result,用于返回每个线程处理后的数据

其中file_processingimage_processing是本人包装好的文件处理方法和图像处理方法,具体实现的代码,这里不贴出来了,源码可查看:

file_processing:《Python常用的模块的使用技巧https://panjinquan.blog.csdn.net/article/details/80805807#file_processing.py

image_processing:《Python常用的模块的使用技巧https://panjinquan.blog.csdn.net/article/details/80805807#image_processing.py

  1. # -*-coding: utf-8 -*-
  2. """
  3. @Project: cluster
  4. @File : thread_operate.py
  5. @Author : panjq
  6. @E-mail : pan_jinquan@163.com
  7. @Date : 2019-03-13 13:43:49
  8. """
  9. from utils import file_processing,image_processing
  10. import threading
  11. import time
  12. threadLock = threading.Lock()#创建线程锁
  13. class FeatureThread(threading.Thread):
  14. def __init__(self, thread_id, func, args=()):
  15. '''
  16. :param thread_id:
  17. :param func:
  18. :param args:
  19. '''
  20. threading.Thread.__init__(self)
  21. self.thread_id = thread_id
  22. self.func = func
  23. self.args = args
  24. def run(self):
  25. print("Starting thread_id:{} ".format(self.thread_id))
  26. # 获得锁,成功获得锁定后返回True, 可选的timeout参数不填时将一直阻塞直到获得锁定, 否则超时后将返回False
  27. # threadLock.acquire() #线程加锁
  28. self.result = self.func(*self.args)
  29. # threadLock.release()# 释放锁
  30. def get_result(self):
  31. try:
  32. return self.result
  33. except Exception:
  34. return None
  35. def test_fun(images_list):
  36. time.sleep(2)
  37. print(images_list)
  38. images=[]
  39. for filename in images_list:
  40. image = image_processing.read_image(filename, resize_height=224, resize_width=224, normalization=False)
  41. images.append(image)
  42. return images
  43. def split_data_list(data_list, split_nums):
  44. '''
  45. :param data_list: 数据列表
  46. :param split_nums: 将列表分成多少块,注意split_nums块必须小于data_list的长度
  47. :return: 返回data_list分块后的索引
  48. '''
  49. data_size=len(data_list)
  50. if split_nums>data_size:
  51. print("illegal arguments,split_nums must be less than len(data_size)")
  52. exit(0)
  53. batch_index=[]
  54. for i in range(split_nums):
  55. start = int(data_size / split_nums * i)
  56. end = int(data_size / split_nums * (i + 1))
  57. if (i == split_nums - 1) :
  58. end = data_size
  59. batch_index.append((start,end))
  60. return batch_index
  61. def thread_test(images_list, nums_thread=4):
  62. thread_collection = []#创建线程容器
  63. # 创建新线程
  64. batch_index=split_data_list(images_list, split_nums=nums_thread)
  65. print("batch_index:{}".format(batch_index))
  66. for i in range(nums_thread):
  67. start,end=batch_index[i]
  68. batch_image_list=images_list[start:end]
  69. thread = FeatureThread(thread_id=i, func=test_fun, args=(batch_image_list,))
  70. thread.start() # 开启新线程
  71. thread_collection.append(thread)# 添加线程到线程列表
  72. # 等待所有线程完成
  73. for thread in thread_collection:
  74. thread.join()
  75. batch_image=thread.get_result()
  76. image_processing.show_image(title="image",image=batch_image[0])
  77. print("Exiting Main Thread")
  78. if __name__=='__main__':
  79. image_dir="../dataset/test_images"
  80. images_list = file_processing.get_images_list(image_dir, postfix=['*.png', '*.JPG'])
  81. print(images_list)
  82. thread_test(images_list, nums_thread=4)

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/143395
推荐阅读
相关标签
  

闽ICP备14008679号