Conceptualizing Threading

Jean-Paul Calderone exarkun at divmod.com
Thu Jun 21 11:32:30 EDT 2007


On Thu, 21 Jun 2007 08:03:22 -0700, JonathanB <doulos05 at gmail.com> wrote:
>
>> You described how threads introduce a problem in your program -- that of
>> generating a sequence of sequential identifiers -- but you didn't describe
>> the problem that threads are solving in your program.  Maybe you don't
>> need them at all?  What led you to threading in the first place?
>>
>> Jean-Paul
>
>Well, the problem I thought they would solve is ensuring everyone got
>a sequential number. But I suppose they wouldn't solve that, since
>from what I gather thread access is somewhat arbitrary. So then, here
>is the crux of the issue. Worst case scenario, this program could be
>accessed by 5-10 people at a time and I need each one to have the
>current information. There are two places I know of that there might
>be multi-access problems.

Alright, so there are multiple short-lived processes.

>
>1) This program is so that we can track one team passing assignments
>to another. Right now I have the names of everyone in team 2 in a
>list. People from team one launch this program and the program grabs a
>pointer (stored in a separate file). If person A launches the program
>and person B launches the program before person A assigns an order,
>they will both have the same pointer, so both orders will go to the
>same person.

And all of these processes have access to the same piece of mutable
state (which happens to be stored on the filesystem).

>
>2) Each assignment has a distinct identifier, which increments by 1
>for each assignment (SR001001, SR001002, etc). Either these can be
>assigned manually (the current method), or they can be assigned
>automatically. If they are assigned manually, I need a way to show
>them the most recent number (that would be easy), if they are assigned
>automatically I need a way to save the number and pass the incremented
>number along (just like the pointer). But I have the same problem here
>as above. If two people launch the program at roughly the same time,
>they will pull the same data. Since these assignments tend to come in
>spurts, concurrent access is likely to be a problem.

It sounds like a lock will do just fine to prevent the race condition
present in the system.  For example, using a class such as this one:
http://twistedmatrix.com/trac/browser/trunk/twisted/python/lockfile.py#L57

you could write your code roughly like this:

    identifierLock = FilesystemLock("/path/to/shared/resource.lock")
    def getNextIdentifier():
        while not identifierLock.lock():
            time.sleep(0.1)
        try:
            # get the current identifier, increment the value in the
            # file, return the incremented value
        finally:
            identifierLock.release()

and you won't have any issues with concurrent access messing up the
identifier state.

>
>So, given those parameters (the rest of this program is a breeze,
>there's a class for each person on Team 2 and the class holds some
>info about them and a dictionary of assignments with the assignment
>number for the key and a value of [assigner, numberAssigned], the only
>other tricky thing for me has been logging because I've never had to
>do much of it before), how can I prevent these problems? The only
>thing that jumps out at me is a server/client model where a server
>runs and compiles all the entries, spitting back the result to each
>individual client. That way, all the working code lives in the server,
>ensuring that the working thread always has the right information,
>while the clients only pass data between the user and the server. But
>I guess that isn't technically multi-threading is it.

You could use a client/server as well, but the server still has to deal
with concurrency somehow.  It could do it in a manner similar to the one
I described above, or it might make sense for it to do something entirely
different - it depends on a lot of details about what the implementation
of the server looks like.

You're right that that isn't multi-threading, though.

Jean-Paul



More information about the Python-list mailing list