Files
h2inc-old/Multiprocessing test/calc_pi.py
2018-02-20 13:59:09 +01:00

172 lines
4.7 KiB
Python

#!/usr/bin/env python3
GUI_WIN = 0
GUI_LINUX = 1
import sys
if sys.platform == 'win32':
GUI = GUI_WIN
else:
GUI = GUI_LINUX
from tkinter import (Tk, BOTH, Text, E, W, S, N, END,
NORMAL, DISABLED, StringVar)
from tkinter.ttk import Frame, Label, Button, Progressbar, Entry
from tkinter import scrolledtext
if GUI == GUI_WIN:
from multiprocessing import Process, Manager, Queue, Value
from queue import Empty
else:
from multiprocessing import Queue, Process
import queue
from decimal import Decimal, getcontext
from time import sleep
DELAY1 = 20
DELAY2 = 20
if GUI == GUI_WIN:
# Queue must be global
q = Queue()
class commonUI(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def initUI(self):
self.val = Value('i', 0)
self.dig = Value('i', 4000)
self.acc = Value('i', 100)
self.parent.title("Pi computation")
self.pack(fill=BOTH, expand=True)
self.grid_columnconfigure(4, weight=1)
self.grid_rowconfigure(3, weight=1)
lbl1 = Label(self, text="Digits:")
lbl1.grid(row=0, column=0, sticky=E, padx=10, pady=10)
self.ent1 = Entry(self, width=10)
self.ent1.insert(END, self.dig.value)
self.ent1.grid(row=0, column=1, sticky=W)
lbl2 = Label(self, text="Accuracy:")
lbl2.grid(row=0, column=2, sticky=E, padx=10, pady=10)
self.ent2 = Entry(self, width=10)
self.ent2.insert(END, self.acc.value)
self.ent2.grid(row=0, column=3, sticky=W)
self.startBtn = Button(self, text="Start", command=self.onStart)
self.startBtn.grid(row=1, column=0, padx=10, pady=5, sticky=W)
self.pbar = Progressbar(self, mode='determinate')
self.pbar.grid(row=1, column=1, columnspan=3, sticky=W+E)
self.pbar.config(value=0, maximum=self.dig.value)
self.txt = scrolledtext.ScrolledText(self)
self.txt.grid(row=2, column=0, rowspan=4, padx=10, pady=5, columnspan=5, sticky=E+W+S+N)
def onStart(self):
self.startBtn.config(state=DISABLED)
self.txt.delete("1.0", END)
digits = int(self.ent1.get())
accuracy = int(self.ent2.get())
self.p1 = Process(target=generatePi, args=(q, digits, accuracy))
self.p1.start()
self.after(DELAY1, self.onGetValue)
def onGetValue(self):
if (self.p1.is_alive()):
self.val.value += 1000
self.update_pbar()
self.after(DELAY1, self.onGetValue)
return
else:
try:
self.txt.insert('end', q.get(0))
self.txt.insert('end', "\n")
self.startBtn.config(state=NORMAL)
except Empty:
print("queue is empty")
def update_pbar(self):
self.pbar.config(value=self.val.value)
class win_Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent, name="frame")
commonUI(parent)
if GUI == GUI_WIN:
# Generate function must be a top-level module funtion
def generatePi(q, digs, acc):
getcontext().prec = digs
pi = Decimal(0)
k = 0
n = acc
while k < n:
pi += (Decimal(1)/(16**k))*((Decimal(4)/(8*k+1)) - \
(Decimal(2)/(8*k+4)) - (Decimal(1)/(8*k+5))- \
(Decimal(1)/(8*k+6)))
k += 1
q.put(pi)
time.sleep(1)
class linux_Example(Frame):
def __init__(self, parent, q):
Frame.__init__(self, parent)
self.queue = q
commonUI(parent)
def generatePi(self, queue):
getcontext().prec = self.digits
pi = Decimal(0)
k = 0
n = self.accuracy
while k < n:
pi += (Decimal(1)/(16**k))*((Decimal(4)/(8*k+1)) - \
(Decimal(2)/(8*k+4)) - (Decimal(1)/(8*k+5))- \
(Decimal(1)/(8*k+6)))
k += 1
print (self.p1.is_alive())
queue.put(pi)
print("end")
def main():
if GUI == GUI_LINUX:
q = Queue()
root = Tk()
root.geometry("400x350+300+300")
app = win_Example(root) if GUI == GUI_WIN else linux_Example(root)
root.mainloop()
if __name__ == '__main__':
main()