2016-03-29 15 views
0

Mobil cihazlarda koştuğumda, 16 basamaklı bellek sorunlarıyla karşılaşan basit bir asal sayı kontrol cihazım var. Bunu, asal sayı denetleyicisinin GUI gibi ayrı bir iş parçacığı üzerinde çalışmasını sağlayarak çözebileceğimi düşündüm. Diğer örneklere bakmak bana yardımcı olmadı, ama bunun yerine farklı örneklerden rastgele parçalar ekledim. Her neyse, buradaki kod.Kivy için GUI'de bellek hatalarını önlemek için hesaplamaları yapmak üzere yeni bir iş parçacığı nasıl başlatırım?

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() 

Eminim ki, daha iyi yapabileceğim bir çok şey var; Ancak, benim için en önemli şey, satır yazdırmanın (threading.activeCount()) 1 yerine 2 basmasıdır. Teşekkürler.

+0

Baskı ifadesine ulaşmadan önce iş parçacığının son işlemin tamamlandığından emin misiniz? – Natecat

+0

Eh, ben baskı beyanını asla doğru yere koymadım. Bir gün için denedim ve yorumunuzu okuduktan ve baskı bildirimi çift satırlarını taşıdıktan sonra şimdi istediğimi yapıyor. Teşekkürler. Bir yan notta, nasıl olduğunu anladığımda soruyu kapatacağım. – pizz

cevap

0

Natecat sayesinde, iş parçacığının yazdırma ifadesinden önce bitirdiği görülüyor. Bir başkası benzer bir sorunla karşılaşırsa, beklediğimi elde etmek için yazdırma ifadesini birkaç satır aşağı

def prime_checker(self, *args): 

     print(threading.activeCount()) 
     ... 

'a aktardım. Hızlı cevap için teşekkürler Natecat.

İlgili konular