Solved

program freezes

Posted on 2011-09-23
16
218 Views
Last Modified: 2012-05-12
I have a part of my program that when the user inputs a value it immediately emails that information ... the problem is while the process is being carried out the entire program freezes ... How could i keep  it from freezing I thinking I should use a tread but my limited understanding of threads is they once activated keep running and I only need it to run on command ... any thoughts ...
0
Comment
Question by:dolamitejenkins
  • 8
  • 4
  • 2
  • +1
16 Comments
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
;-)

I think that you mean "thread", not "tread" ;-)

Based upon the description, yes, a thread may help you.
What appears to be happening is that a call is being made to a routine that is taking a long time to complete (i.e., the "sendMail()" routine).

What a thread would allow you to do is to start a separate (yet associated) routine call to perform the actual "sendMail()" processing, and yet allow your program to continue.

However, you need to be aware of what can happen when threads are used.

This appears to be a reasonable description of things of which you should be aware:

http://linuxgazette.net/107/pai.html
0
 

Author Comment

by:dolamitejenkins
Comment Utility
thanks can you think of an example ?
0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
An example of threading?

The link from above has examples, with explanations.

Or am I missing something?
0
 
LVL 16

Expert Comment

by:gelonida
Comment Utility
You should rally read HonorGod's link.
It gives a good understanding of the basics of threads


A very simple solution to what you are looking for is shown below.
However not knowing the detials of your code this might be too simple
and cause problems as it uses neither queuing nor Locks.

Let's assume this is your old code:

# ---------- old code
.
.
.
some_code()
send_mail(destination, subject, message)
d_something_else()
# ---- end of old code


# ---------- new code
import threading # put this at the beginning of your file,
.
.
.
some_code()
my_send_thread = threading.Thread(target=send_mail,
    args=(destination, subject, message) )
my_send_thread.start()
d_something_else()
.
.
.
# ---- end of new code


Please be aware, that Threading has some inherent 'dangers'.

You should for example think, what would happen if you
the second email is sent, while the first email hasn't been finished to be sent.
Is the function send_mail() thread save (can it be executed twice at the same time)?
. . .

If it might be possible, that you would send many mails in parallel,
then  above oversimplified code would be a bad solution and you
should start one thread, that 'dequeues' emails to be sent and your main thread,
which enqueues the emails to be sent.

Alternatively you can use Locks. this would mean, that only one mail is sent at a time.




0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
@gelonida - good update!  excellent warnings.
0
 

Author Comment

by:dolamitejenkins
Comment Utility
thanks
0
 

Author Comment

by:dolamitejenkins
Comment Utility
Not grasping threading for some reason ... the conditions  ... Im working on some code now... will keep updated
0
 

Author Comment

by:dolamitejenkins
Comment Utility
what condition am I waiting for to activate the email thread ? and how do I make it only activate once then wait for the condition again... I know this code is a mess but for some reason I'm not understanding threading ...

import threading # put this at the beginning of your file, 

	self.Hosp = wx.Button(panel, -1, 'Hospital', size=(-1, 30), pos =(500,150))
	wx.StaticText(panel, -1, 'Transport Destination', pos=(485, 182))
        self.Hosp.Bind(wx.EVT_BUTTON, self.OnSendsperemail,self.Hosp)

def OnSendsperemail(self,event):
	self.Hospital1 = self.led.GetValue()
	try:
	    f =open("superviser.txt","r")
	    self.emailsupr = f.readline() # reads the lines
	    f.close()
	except IOError:
	    pass

class Emailthreading (threading.Thread, InsertData):
        
		my_send_thread = threading.Thread(target=send_mail,
		    args=(destination, subject, message) )
		my_send_thread.start()


	def run(self,event):
		self.Hospital1 = self.led.GetValue()

		while True:
	
			try:
			    f =open("superviser.txt","r")
			    self.emailsupr = f.readline() # reads the lines
			    f.close()
			except IOError:
			    pass
	
	def OnSendspermailnext(self,event):
		try:
		    
		    pdfmime=''
		    self.filename=''
		    self.sender = "SEMS ALERT !"
		    self.recipient = self.emailsupr
		    self.destinattion= self.tc69.GetStringSelection()
		    self.subject = "Supervisor Alert !"	    
		    
		    
		    
		    fromaddr = "SEMS ALERT !"
		    toaddr = self.recipient
		    msg = MIMEMultipart()
		    msg['From'] = self.sender
		    msg['To'] = self.recipient
		    msg['Subject'] = "Supervisor Alert !"	   
	
		    body = "Please be advised a patient is being transported to the following hospital \n"
		    body += (self.destinattion)
		    msg.attach(MIMEText(body, 'plain'))
		    server = smtplib.SMTP('smtp.gmail.com', 587)
		    server.ehlo()
		    server.starttls()
		    server.ehlo()
		    server.login("semsnation@gmail.com", "frogman$")
		    text = msg.as_string()
		    server.sendmail(fromaddr, toaddr, text)
		    server.quit()
	
		    
		    
		except IOError:
		    dlg = wx.MessageDialog(self, "There Was An Error Sending Your Email", caption = "Your Email Was Not Sent" , style = wx.OK | wx.ICON_ERROR)
		    dlg.ShowModal()
		    dlg == wx.OK 
		    self.dlg1a.Destroy()

Open in new window

0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
Wow, you asking some fundamental questions about concurrency.

As far as this question is concerned:

Q: What condition am I waiting for to activate the email thread?
A: One way to think of it is by thinking about "permission".
    What is permission?  Well, there is some token, that only exists once in the program,
    and to get permission, you have to wait for this token (called a mutual exclusion
    semaphore - or mutex).  If no one (no thread) currently has the token, then the first
    thread to "ask" for it, gets it.  Then, as long as this thread "keeps it" (i.e., doesn't
    release it), then any other thread that wants it has to wait.
    Eventually, the thread that owns the token releases it, and one of the waiting
    threads is given the token.  All other threads continue waiting.

  This site may help: http://www.daniweb.com/software-development/python/tutorials/238590
0
 

Author Comment

by:dolamitejenkins
Comment Utility
thanks HonorGod
0
 
LVL 28

Expert Comment

by:pepr
Comment Utility
Think about a thread as about the run of a separate program (a running program is usually called a process).  The only difference with threads is that they share the same memory.  The thread can access the variables (it can change them).  Because of that the threads must be careful when working with the resources.  One thread should not do something wrong with respect to the other thread.  Say one thread needs A and B to continue.  Say there is another thread that also needs A and B.  Say, that the threads are not careful enough and the first one takes A, the second one takes B and then both want to take the other resource that is already not there.  This situation is called a deadlock.  You may observe it as a "frozen program". It can happen even when both A and B resources were obtained using the mechanism of mutual exclusion.

There are other situations similar to a deadlock.  Moreover, even when such a wrong situation does not happen, the threads still can mutually affect the behaviour of the all others.  Because of that you have to learn a bit of theory first.

Have a look at http://en.wikipedia.org/wiki/Deadlock
0
 

Author Comment

by:dolamitejenkins
Comment Utility
pepr thanks... so I should be able to call the thread the same way I call  a module or function ? then have the thread run as long as the condition remain true ? ...
0
 
LVL 28

Expert Comment

by:pepr
Comment Utility
Well, see the gelonida's http:#36589101.  The earlier send_mail() function (in the older solution) was passed to the threading.Thread() constructor of the object, and then the thread object (named my_send_thread) was started. Since then the function send_mail behaves as if it was executed normally.  However, the function should be aware of running in a thread.  Simply said, the send_mail() runs until its end and then also the thread ends its run.

The thread runs in parallel with the code that called the my_send_thread.start().  The code can do other things.  Then the main code usually waits for finishing the thread, like my_send_thread.join() -- see http://docs.python.org/library/threading.html#threading.Thread.join

Do you mean that conditio? http://docs.python.org/library/threading.html#condition-objects

0
 
LVL 16

Accepted Solution

by:
gelonida earned 500 total points
Comment Utility
Hm please look at following small attachment.
Run it, play with it. Perhaps it helps undertstanding.

Please look at the documentaiton if Queue
http://docs.python.org/library/queue.html

This example has two threads, but the mailer threads always sleeps as long as no mail has to be sent.
import threading
import time
import Queue

mail_queue = Queue.Queue()

def user_interface_code():
    """ supposed to run in main thread """
    destination = 'mister.X@unknown.destination'
    counter = 0
    while True:
        print "Please enter a new message (or return to quit)"
        message = raw_input()
        subject = 'message %d' % counter
        counter += 1
        print "enqueueing message"
        print "msg %r" % message
        if message == '': # last message?
            message=None 
            mail_queue.put( (None, None, None) )
            return 
        mail_queue.put( (destination, subject, message) )

def sendmail(destination, subject, message):
    print "sending mail to",  destination
    print "subject:", subject
    print "message size ", len(message)
    time.sleep(4)
    print "mail was sent"

def mailer_thread():
    """ supposed to run in separate thread """
    while True:
        destination, subject, message = mail_queue.get()
        if message is None: # terminate thread if message is None
            print "Terminating mailer Thread"
            return 
        sendmail(destination, subject, message)

if __name__ == "__main__":
    mail_thread = threading.Thread(target = mailer_thread)
    mail_thread.start()
    user_interface_code()

Open in new window

0
 

Author Comment

by:dolamitejenkins
Comment Utility
thank you playing with it now ....will keep you updated
0
 

Author Closing Comment

by:dolamitejenkins
Comment Utility
thank you
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

This article will show the steps for installing Python on Ubuntu Operating System. I have created a virtual machine with Ubuntu Operating system 8.10 and this installing process also works with upgraded version of Ubuntu OS. For installing Py…
Dictionaries contain key:value pairs. Which means a collection of tuples with an attribute name and an assigned value to it. The semicolon present in between each key and values and attribute with values are delimited with a comma.  In python we can…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now