Article View: comp.os.os2.programmer.misc
Article #244Re: Thread-specific variables?
From: Q
Date: Mon, 04 Oct 1993 12:13
Date: Mon, 04 Oct 1993 12:13
102 lines
5166 bytes
5166 bytes
In <28ins7$fvv@tinman.dev.prodigy.com> bob@tinman.dev.prodigy.com (Bob Dedrick) writes:
>In article <28efue$478@access.digex.net> kbennett@access.digex.net (Keith R. Bennett) writes:
>>
>>I have a question about thread programming. Is there any way to make
>>a given variable specific to an instance of a thread?
>>
>>[...]
>There is no way (that I know of) to make a *global* variable specific to
>a thread. However, since each thread has its own stack, any variables
>allocated on the stack (as automatics or using _alloca()) will be thread-
>specific.
After having to deal with this kind of crap since version 1.(1 or 2, I can't
remember), I can say that after designing/implementing many different inter-
thread communication mechanisms, I find that the easiest to use is the
following:
1) Define two user messages
#define MYM_STARTTHREAD (WM_USER)
#define MYM_ENDTHREAD (WM_USER+1)
2) For every type of asynchronous action needed, allocation 1 bit out of
a total of 32 for it and define a constant for it. E.g.,
#define ASYNC_OPEN 0x00000001L
#define ASYNC_PRINT 0x00000002L
For each window class, create a ULONG field in the instance data to
hold the bits corresponding to the threads started by windows of this
class.
3) Also, for each action, define a structure containing all variables to
be *sent* to the thread and all variables to be *returned* from the
thread. The first field *MUST* be a ULONG containing the size of the
structure for the purposes of communicating to PM the amount of memory
to thunk, should that be required in a system call.
You might want to also create a common THREADINFO structure containing
fields that all threads will have, to save you some typing.
4) Whenever a window needs to perform some lengthy processing, it sends
itself a MYM_STARTTHREAD with LONGFROMMP(mpParm1) specifying the type
of thread required and PVOIDFROMMP(mpParm2) pointing to an *already
initialized* thread structure (see step 3) to be passed to the thread.
The message processing can first cast this pointer to PTHREADINFO
(assuming you typedef'd one as recommended) to initialize the common
fields (one that is needed is the window handle of the "owning" thread).
It then switch's on the thread type in order to: malloc() a block to
copy this thread-specific structure into, in case the pointer passed in
pointed to an automatic variable, and also to determine the procedure for
the thread. Finally, it calls _beginthread to start the thread,
specifying the pointer to the malloc()'d block as the parameter to the
thread.
The thread receives this pointer, does its stuff, sets the variables to
be communicated back to the window in the structure and executes the
following code (assuming the definitions at the beginning):
VOID _Optlink mythread(PMYTHREADINFO pmtiInfo)
{
:
WinPostMsg(pmtiInfo->hwndOwner,
MYM_ENDTHREAD,
MPFROMLONG(ASYNC_SOMETHING),
MPFROMP(pmtiInfo);
DosEnterCritSec();
pmtiInfo->bThreadDead=TRUE;
}
The owning window resets the bit in its ULONG to specify that the
thread is no longer active and free()'s the memory (after executing
the following loop to insure that the thread is dead)
while (!pmtiInfo->bThreadDead) DosSleep(0);
Of course, any return codes from the thread (via the structure) are
checked, etc.
What are the advantages of this method?
1) Look Ma, no global variables!
2) The procedure of the owning window can intercept the WM_MOUSEMOVE and
WM_CONTROLPOINTER messages and return the appropriate value to specify
SPTR_WAIT should the ULONG ulAsync variable in its instance data be
non-zero. This provides excellent user-feedback. Additionally, the
WM_INITMENU can be intercepted and any menu items needed can be
disabled depending on which threads are active.
Any questions can be directed to me either through the conference or email.
Cheers,
Q
--
Have you read this month's EDM/2? It's available via anonymous FTP to
ftp.cdrom.com in the /pub/os2/2_x/program/newsltr directory. New articles,
comments, suggestions, and Q&A questions are always welcome! Send all to
os2man@panix.com .
Technical Details
Message-ID:
<28p41g$k3s@panix.com>Path:
arc1-ca.pugleaf.net!gmd.de!newsserver.jvnc.net!darwin.sura.net!emory!swrinde!cs.utexas.edu!uunet!panix!not-for-mailReferences:
<28efue$478@access.digex.net> <28ins7$fvv@tinman.dev.prodigy.com>Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 11307a,b690185ddc355787 X-Google-Attributes: gid11307a,public X-Google-Thread: 10cd94,b690185ddc355787 X-Google-Attributes: gid10cd94,public X-Google-ArrivalTime: 1993-10-04 05:22:57 PST Path: arc1-ca.pugleaf.net!gmd.de!newsserver.jvnc.net!darwin.sura.net!emory!swrinde!cs.utexas.edu!uunet!panix!not-for-mail From: os2man@panix.com (Q) Newsgroups: comp.os.os2.programmer.misc,bit.listserv.os2-l Subject: Re: Thread-specific variables? Date: 4 Oct 1993 08:13:36 -0400 Organization: PANIX Public Access Internet and Unix, NYC Lines: 102 Message-ID: <28p41g$k3s@panix.com> References: <28efue$478@access.digex.net> <28ins7$fvv@tinman.dev.prodigy.com> NNTP-Posting-Host: panix.com