Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 234
  • Last Modified:

program freezes

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
dolamitejenkins
Asked:
dolamitejenkins
  • 8
  • 4
  • 2
  • +1
1 Solution
 
HonorGodCommented:
;-)

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
 
dolamitejenkinsAuthor Commented:
thanks can you think of an example ?
0
 
HonorGodCommented:
An example of threading?

The link from above has examples, with explanations.

Or am I missing something?
0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
gelonidaCommented:
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
 
HonorGodCommented:
@gelonida - good update!  excellent warnings.
0
 
dolamitejenkinsAuthor Commented:
thanks
0
 
dolamitejenkinsAuthor Commented:
Not grasping threading for some reason ... the conditions  ... Im working on some code now... will keep updated
0
 
dolamitejenkinsAuthor Commented:
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
 
HonorGodCommented:
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
 
dolamitejenkinsAuthor Commented:
thanks HonorGod
0
 
peprCommented:
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
 
dolamitejenkinsAuthor Commented:
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
 
peprCommented:
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
 
gelonidaCommented:
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
 
dolamitejenkinsAuthor Commented:
thank you playing with it now ....will keep you updated
0
 
dolamitejenkinsAuthor Commented:
thank you
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 8
  • 4
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now