chicken-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Chicken-users] Still having problems with threading


From: Shawn Rutledge
Subject: Re: [Chicken-users] Still having problems with threading
Date: Mon, 27 Apr 2009 13:56:13 -0700

On Sun, Apr 26, 2009 at 7:54 AM, William Ramsay <address@hidden> wrote:
> Basically, what I want to do is interrupt the thread with a key stroke.
> While the thread is doing it's thing - let's say printing a count to
> standard out - I want to be able to hit a key and stop it.   I guess the
> problem I'm having trouble understanding is how I switch between the
>  primordial thread (t0) and the one I've started (t1).   If t1 is in a loop
> that that checks if it should keep going (i.e. the count example in SRFI-18)
> how do I insert into that loop a check for what t0 is doing - or better, how
> do I allow t0 to do anything?    It's one thing to say add to counterA and
> then add to counterB, one of which is in thread  0 and the other of which is
> in t1.   It's another thing to pick up an interrupt (i.e. a key stroke) that
> may come at any time.

A counter is not "in" a thread.  Either thread can write to the same
word in memory, and that's a good way to communicate between threads.
It's the non-atomic stuff (like larger blocks of memory being updated)
that you have to watch out for: have to make it transactional.

But reading from the keyboard involves a system call: ask the OS to do
it, and then literally sit and wait until the OS gives you a response.

The trouble with the Chicken thread implementation is that if one
thread does blocking I/O, all threads will be blocked.  So you just
have to do non-blocking I/O: check to see if there is a keystroke but
don't wait for one, in your example.  t0 can set! a variable to which
t1 has access when the keystroke is detected, and then t1 can stop
next time it checks that variable.

My way (one of them) was to write a C function to do the polling (all
of /dev/input/event*), and call it from a Scheme event loop in the
primordial thread.  I used select() though, which blocks for a short
time.  chicken has an internal select() too, and there is a way to add
your own file descriptors to the list that select() is waiting for, so
in theory you can use blocking I/O on those descriptors, but I didn't
do it that way for some reason... forgot why.

http://dscm.svn.sourceforge.net/viewvc/dscm/src/dsinp/evdev.c?view=markup

There is one loophole for blocking I/O: TCP socket operations do not
block threads.  So, another alternative is to move your blocking I/O
into a separate process, and the main chicken process can start a
thread which uses TCP to connect to that process and request the
blocking I/O to be done on its behalf.  You can use a thread which
blocks while waiting for the response from that socket, and it will
not block the rest of the threads.  So I experimented with handling
input events that way (made a sort of "input server"), but I got some
latency, more than I expected, which was tolerable for the keyboard
but quite noticeable for touchscreen events.  I didn't figure out
where exactly the overhead is, seems like it may be taking longer to
construct the event objects than to receive them.  My goal was to use
the same API for reading from "local" (/dev/input nodes right in the
main program), "remote" input devices (connect via socket to the input
server), and X11 or other window-system input devices too.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]