0
私はモバイルデバイスで実行したときに16桁のメモリ問題に遭遇した単純な素数チェッカーを持っています。私はprime_numberチェッカーを別のスレッドでGUIとして実行させることでこれを解決できると考えました。他の例を見てもわかりませんが、別の例のランダムな部分を追加したようです。とにかくここにコードがあります。kivyのGUIでメモリエラーを防ぐために新しいスレッドを計算を開始するにはどうすればよいですか?
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.properties import ObjectProperty
from kivy.clock import mainthread
from kivy.lang import Builder
from numpy import remainder, sqrt, floor
from datetime import datetime
import threading
Builder.load_string('''
<MainScreen>:
number: number_input
check: check_button
answer: answer
time: time
canvas:
Color:
rgba: .2, .2, .5, .5
Rectangle:
pos: self.pos
size: self.size
# answer button
Color:
rgba: .5, .8, .8, .5
Rectangle:
pos: 0, root.height/3
size: root.width/2, root.height/10
# time button
Color:
rgba: .2, .5, .5, .5
Rectangle:
pos: 0, root.height/6
size: root.width, root.height/10
TextInput:
id: number_input
pos: root.width/4, 2 * root.height/3
size: root.width/2, root.height/10
multiline: False
input_filter: 'int'
hint_text: 'Enter number'
write_tab: False
Button:
id: check_button
pos: root.width/2, root.height/3
size: root.width/2, root.height/10
text: 'Check'
on_press:
root.start_second_thread()
Label:
id: answer
text: 'Answer'
pos: 0, root.height/3
size: root.width/2, root.height/10
Label:
id: time
pos: 0, root.height/6
size: root.width, root.height/10
text: 'Time taken'
''')
class MainScreen(Widget):
number = ObjectProperty(None)
check = ObjectProperty(None)
answer = ObjectProperty(None)
time = ObjectProperty(None)
def start_second_thread(self):
thread2 = threading.Thread(target=self.prime_checker)
thread2.start()
#thread2.join()
print(threading.activeCount())
def prime_checker(self, *args):
ans = ''
now = datetime.now()
if self.number.text == '':
#self.answer.text = 'No number entered'
ans = 'No number entered'
end = datetime.now() - now
#self.time_checker(end)
elif len(self.number.text) > 17:
#self.answer.text = 'Too big for now'
ans = 'Too big for now'
end = datetime.now() - now
#self.time_checker(end)
else:
numb = int(self.number.text)
upper_limit = int(floor(sqrt(numb)))
tested = False
if numb < 2:
#self.answer.text = 'Not Prime'
ans = 'Not Prime'
end = datetime.now() - now
#self.time_checker(end)
elif numb == 2:
#self.answer.text = 'Prime'
ans = 'Prime'
end = datetime.now() - now
#self.time_checker(end)
elif numb % 2 == 0:
#self.answer.text = 'Not Prime, 2'
ans = 'Not Prime, 2'
end = datetime.now() - now
#self.time_checker(end)
else:
for i in range(3, upper_limit, 2):
#if numb % i == 0:
if remainder(numb, i) == 0:
#self.answer.text = 'Not Prime, {}'.format(i)
ans = 'Not Prime, {}'.format(i)
tested = True
end = datetime.now() - now
#self.time_checker(end)
break
if tested == False:
#self.answer.text = 'Prime'
ans = 'Prime'
end = datetime.now() - now
#self.time_checker(end)
self.update_main_thread(ans, end)
def time_checker(self, some_time):
some_time = 'This took {0} seconds and {1} milliseconds'.format(some_time.seconds, float(some_time.microseconds)/1000)
#self.time.text = some_time
@mainthread
def update_main_thread(self, ans, tim):
self.answer.text = ans
tim = 'This took {0} seconds and {1} milliseconds'.format(tim.seconds, float(tim.microseconds)/1000)
self.time.text = tim
class PrimeNumberCheckerApp(App):
def build(self):
return MainScreen()
if __name__ == '__main__':
PrimeNumberCheckerApp().run()
私はより良いことをすることができるたくさんのものがあると確信しています。しかし、私にとって最も重要なことは、なぜline print(threading.activeCount())が2ではなく1を出力するのかということです。
printステートメントに入る前にスレッドが単純に終了していないことは確かですか? – Natecat
まあ、私はprint文を決して正しい場所に置かないと思います。あなたのコメントを読んだり、プリントステートメントのカップルラインを移動したりして、今、私が望んでいたことをやっている。ありがとう。 補足として、方法を見つけたら質問を閉じることにします。 – pizz