Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are
spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the
password reset link.
Due to spam on this forum, all posts now need moderator approval.
Entire forum
➜ MUSHclient
➜ General
➜ Threading problems.
It is now over 60 days since the last post. This thread is closed.
Refresh page
Posted by
| Mudguy
(4 posts) Bio
|
Date
| Wed 10 Aug 2005 04:23 PM (UTC) |
Message
| Let's take this Python script, timer.py:
from time import clock
import threading
def sleep(num, func, test, args):
fire = clock() + num
while clock() < fire:
if not test():
return
func(*args)
def balance(num, func, test, args = [], tar = sleep):
t = threading.Thread(target = tar, kwargs = locals())
t.start()
and a plugin:
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<!-- Saved on Thursday, July 21, 2005, 9:57 PM -->
<!-- MuClient version 3.66 -->
<muclient>
<plugin
name="Bazzinator"
author="mudguy"
id="bd3b5b5ec7994dc41dfbd2ca"
language="Python"
purpose="To bazzinate the foobar"
save_state="y"
date_written="2005-07-21 21:57:00"
requires="3.66"
>
</plugin>
<!-- Get our standard constants -->
<include name="constants.pys"/>
<!-- Script -->
<script>
<![CDATA[
import timer
def foo():
timer.balance(10, baz, bar)
def bar():
return True
def baz():
world.Note('Done!')
]]>
</script>
</muclient>
Now, when I run this, it chugs along fine for the 10 seconds while the thread runs, but as soon as it calls baz Windows tells me that MUSHclient 'has run into problems and must be shut down'. This is decidedly weird, since with the send details box open, I can still input commands to MUSHclient and receive lines from the server back. If someone tells me how to extract the information provided by this dialogue box (some DLLs referenced and a hex dump, I think), I can provide that as well, but as it is now I can only look at it and not copy it. This is on XP Professional, SP 2, with MUSHclient 3.66.
I know this can be done with MUSHclient timers instead, but I'm planning to expand this to things that can't be done with those.
So what am I doing wrong? Or how can I work around this problem? | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #1 on Wed 10 Aug 2005 04:52 PM (UTC) |
Message
| Well, this would depend on whether or not MUSHclient expects plugins to come along at random times and make API calls - in other words, it has to be thread-safe and all that. Nick's the only one who would know that for sure. |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Larkin
(278 posts) Bio
|
Date
| Reply #2 on Wed 10 Aug 2005 06:47 PM (UTC) |
Message
| Why not just use MUSHclient's timers, since that appears to be what you're (re)implementing with your thread? | Top |
|
Posted by
| Mudguy
(4 posts) Bio
|
Date
| Reply #3 on Wed 10 Aug 2005 08:40 PM (UTC) |
Message
| As I said in the oriinal post, this is going to be extended further into something that MUSHclitn timers can't deal with. One thing to be done is to give MUSHclient access to page scraping and news feeds, removing all the tiresome window swapping and pushing of F5. Along this thread (excuse the pun), MUSHclient could also be given Instant Messaging capacity. Other large tasks that are too long to be done linearly and would need to call the API are also possible. | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #4 on Wed 10 Aug 2005 08:47 PM (UTC) |
Message
| Are you basically aiming to turn MUSHclient into a centralized information repository of sorts? A MUD client that also hooks into feeds, news pages, instant messaging, etc.? |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Ked
Russia (524 posts) Bio
|
Date
| Reply #5 on Sat 13 Aug 2005 05:27 AM (UTC) |
Message
| The solution to this exists, though you have to know where to look for it. You should look at Python/Lib/site-packages/win32com/test/testMarshall.py for firsthand example, but here's a snippet that's a bit simpler:
import thread, pythoncom
from time import sleep
from win32com.client import Dispatch
class Ticker(object):
def __init__(self, func, world):
self.keep_alive = False
self.interval = 0.1
self.lock = thread.allocate_lock()
if callable(func):
self.func = func
else:
raise Error, "Argument passed to the Ticker class must be a callable object, got %s instead." % str(type(func))
if world:
self.mc = Dispatch(world)
else:
self.mc = None
def start(self):
#Marshal the caller object ('World' ref dispatched above) so it can be passed into the timer thread
stream = pythoncom.CoMarshalInterThreadInterfaceInStream(pythoncom.IID_IDispatch, self.mc._oleobj_)
#start timer thread using the Run method and passing the marshaled stream object to it
self.keep_alive = True
thread.start_new_thread(self.run, (stream,))
def run(self, stream):
#COM must be initialized manually in secondary threads
pythoncom.CoInitialize()
#extract the World interface from stream and release the latter
caller = pythoncom.CoGetInterfaceAndReleaseStream(stream, pythoncom.IID_IDispatch)
world = Dispatch(caller) #caller is dispatched in this thread's context now
while self.keep_alive:
self.lock.acquire()
self.func(world)
self.lock.release()
sleep(self.interval)
world = None
pythoncom.CoUninitialize()
def stop(self):
self.keep_alive = False
def setInterval(self, interval):
self.lock.acquire()
self.interval = interval
self.lock.release()
You are interested primarily in Ticker.start() and Ticker.run() Basically, you need to marshal the world object into the new thread, after which it is safe to be used from there. If, however, you try to use an "unmarshalled" world object from a separate thread, it's almost guaranteed to cause a crash. | Top |
|
The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).
To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.
20,089 views.
It is now over 60 days since the last post. This thread is closed.
Refresh page
top