pythonマルチスレッドthreading
2038 ワード
最近双線形補間のアルゴリズムを見て、自分で以下を実現したいと思って、1つのプログラムを書いて、時間を測って、1080*1564の1枚の証明書の写真を補間resizeを通じて600*800まで15 sかかりました....
そこでthreadingマルチスレッドでやろうと、3つのサブスレッドが3つのチャネルをそれぞれ補間して、速度が3倍になるのではないでしょうか.結局15 sで、本当に納得できず、pythonマルチスレッドについて調べてみたら、やっと分かった
pythonの世界ではGIL(Global Interpreter Lock)と言わざるを得ないが,存在するためCPU時間当たり1スレッドしか実行できないため,シングルコアCPU下のpythonマルチスレッドは同時処理のみで並列処理はできない.
pythonでは、GILの解放ロジックは、IOオペレーションまたはticksテクノロジーがしきい値に達すると、GILが解放され、他のスレッドが起動され、GIL上のCPUに競合して実行されます.この競合モードは、先にサービスしたり、短いジョブを優先したり、タイムスライスを回転したりする可能性があります.
そこでthreadingマルチスレッドでやろうと、3つのサブスレッドが3つのチャネルをそれぞれ補間して、速度が3倍になるのではないでしょうか.結局15 sで、本当に納得できず、pythonマルチスレッドについて調べてみたら、やっと分かった
from PIL import Image
from datetime import datetime
import matplotlib.pyplot as plt
import numpy as np
import math
import os
from threading import Thread
from multiprocessing import Process
img_path = r'C:\Users\king\Pictures\ \ _20190731154219.jpg'
img_arr = np.array(Image.open(img_path), np.uint8)
target_size = (800, 600, 3)
global resized_img
resized_img = np.zeros(target_size)
cur_size = img_arr.shape
ratio_x, ratio_y = target_size[0] / cur_size[0], target_size[1] / cur_size[1]
def cal(i, j, x, y, c):
global resized_img
# print('this is the thread {}'.format(c))
t_left_x, t_left_y = math.floor(x), math.floor(y)
p1 = (t_left_x+1 - x)*img_arr[t_left_x, t_left_y, c] + (x - t_left_x)*img_arr[t_left_x+1, t_left_y, c]
p2 = (t_left_x+1 - x)*img_arr[t_left_x, t_left_y+1, c] + (x - t_left_x)*img_arr[t_left_x+1, t_left_y+1, c]
v = (t_left_y+1 - y)*p1 + (y - t_left_y)*p2
resized_img[i, j, c] = v
def bilinear(c):
a = [cal(i, j, i/ratio_x, j/ratio_y, c) for i in range(target_size[0]) for j in range(target_size[1])]
if __name__ == '__main__':
start = datetime.now()
threads = []
for c in range(3):
t = Thread(target=bilinear, args=(c,))
threads.append(t)
t.start()
for t in threads:
t.join()
# print(resized_img)
end = datetime.now()
seconds = (end-start).seconds
print('process cost {}s'.format(seconds))
resized_show = Image.fromarray(resized_img.astype(np.uint8))
plt.imshow(resized_show)
plt.show()
pythonの世界ではGIL(Global Interpreter Lock)と言わざるを得ないが,存在するためCPU時間当たり1スレッドしか実行できないため,シングルコアCPU下のpythonマルチスレッドは同時処理のみで並列処理はできない.
pythonでは、GILの解放ロジックは、IOオペレーションまたはticksテクノロジーがしきい値に達すると、GILが解放され、他のスレッドが起動され、GIL上のCPUに競合して実行されます.この競合モードは、先にサービスしたり、短いジョブを優先したり、タイムスライスを回転したりする可能性があります.