RU/2: Форум. Общение пользователей и разработчиков OS/2 (eCS). : Ответить на сообщение
Имя:
e-mail:
FIDO:
Home page:
сохранить данные о вас
Тема:
> The OS/2 APIs DosWaitThread, DosEnterCritSec, and DosExitCritSec > > 1. DosWaitThread() > > It has two basic modes of operation. This function allows a thread to wait or check > for completion of another thread. > Places the current thread into a wait state until another thread in the > current process has ended. It then returns the thread identifier of the ending > thread. It can wait for a specific thread, by specifying the thread's ID, or it can wait > for any thread termiantion in the process, by spcifying 0 for the tread ID. > > > Syntax: > > #define INCL_DOSPROCESS > #include <os2.h> > > PTID ptid; /* Address of the thread identification. */ > ULONG option; /* An indicator that specifies whether to return if no thread has ended. */ > APIRET ulrc; /* Return Code. */ > > ulrc = DosWaitThread(ptid, option); > > Prototype: > > APIRET DosWaitThread(PTID ptid, Ulong option); > > > Parameters: > > ptid (PTID) - in/out - Address of the thread identification. > > > Input - The address of the ThreadID of the thread of interest. If ptid > is 0, the current thread waits until the next thread in the > process has ended. If ptid is nonzero, the current thread waits > until the indicated thread has ended. > > Output - The ThreadID of the ended thread is returned in this field. > > option (ULONG) - input > An indicator that specifies whether to return if no thread has ended. > > The values of this field are shown in the following list: > > 0 - DCWW_WAIT > The current thread waits until a thread ends. If a thread has > already ended, the call returns immediately with the ptid. > > 1 - DCWW_NOWAIT > The current thread does not wait if no threads have ended. > > ulrc (APIRET) - returns : Return Code. > > DosWaitThread returns one of the following values: > > 0 NO_ERROR > 95 ERROR_INTERRUPT > 294 ERROR_THREAD_NOT_TERMINATED > 309 ERROR_INVALID_THREADID > > Remarks: > > DosWaitThread is used to wait for termination of threads within a process. It > is usually used so that thread resources (for example, the stack) can be > recovered when a thread ends. > > DosWaitThread waits on any thread within the current process, or on a specific thread within the process, based on the ptid parameter's contents. option allows the caller the option of waiting until a thread ends, or getting immediate return and status. > > If no thread has ended and the DCWW_NOWAIT option is specified, the ptid field is preserved. > > If DosWaitThread is called with the input ptid set to the current thread (the > thread attempts to wait on its own termination), the ERROR_INVALID_THREADID error > code is returned. > > ERROR_INVALID_THREADID is also returned if a caller attempts to wait on the termination > of the thread with a ptid of 1. > > Example: > > This example creates a new thread within a process, sleeps for 1 second, > suspends the thread for 5 seconds, and then waits for the thread to > terminate. > > Compile this example with MULTITHREAD LIBRARIES. If you are using C/2, > use the /Gm+ switch. > > #define INCL_DOSPROCESS /* Process and thread values */ > #define INCL_DOSERRORS /* DOS error values */ > #include <os2.h> > #include <stdio.h> > > void _System CntThreadProc(ULONG LoopMax); /* Count Thread */ > > int main(VOID) { > > > TID tidCntThread = 0; /* ID returned for newly created thread */ > PFNTHREAD pfnCntThread = &CntThreadProc; /* Address of thread program */ > ULONG ulThreadParm = 100; /* Parameter to thread routine */ > APIRET rc = NO_ERROR; /* Return code */ > > rc = DosCreateThread(&tidCntThread, /* Thread ID (returned by function) */ > pfnCntThread, /* Address of thread program */ > ulThreadParm, /* Parameter passed to ThreadProc */ > CREATE_READY | /* Thread is ready when created */ > STACK_SPARSE, /* Do not pre-commit stack pages */ > 8192L); /* Stack size, rounded to page bdy */ > > if (rc != NO_ERROR) { > > printf("DosCreateThread error: return code = %u\n", rc); > return 1; > } > > rc = DosSleep (1000); /* Sleep for a second to allow thread to run a bit */ > rc = DosSuspendThread (tidCntThread); > > if (rc != NO_ERROR) { > > printf("DosSuspendThread error: return code = %u\n", rc); > return 1; > } > > rc = DosSleep (5000); /* Sleep 5 seconds before resuming the thread */ > > rc = DosResumeThread (tidCntThread); > > if (rc != NO_ERROR) { > > printf("DosResumeThread error: return code = %u\n", rc); > return 1; > } > > rc = DosWaitThread (&tidCntThread, DCWW_WAIT); > > if (rc != NO_ERROR) { > printf ("DosWaitThread error : return code = %u\n", rc); > } > > printf ("Thread has completed!\n"); > > return NO_ERROR; > } > > void _System CntThreadProc(ULONG LoopMax ) /* Count thread */ > { > ULONG i = 0; /* Loop index */ > > for (i=0;i < LoopMax;i++ ) { > printf ("%d\n", i); > } > > return; > } > > > 2. DosEnterCritSec() > > The DosEnterCritSec() function disables all thread rescheduling for the current process. > > Syntax: > > #define INCL_DOSPROCESS > #include <os2.h> > > APIRET ulrc; /* Return Code. */ > > ulrc = DosEnterCritSec(); > > Prototype: > > APIRET DosEnterCritSec(void); > > > Parameters: > > ulrc (APIRET) - returns: Return Code. > > DosEnterCritSec returns one of the following values: > > 0 NO_ERROR > 309 ERROR_INVALID_THREADID > 484 ERROR_CRITSEC_OVERFLOW > > Remarks: > > DosEnterCritSec causes all other threads in the process to block themselves > and give up their time slice. > > After a DosEnterCritSec request is made, no functions should be called that depend on another thread to do processing until DosExitCritSec has completed. > > !! Great care should be taken when using compiler runtime functions and other OS/2 functions after a DosEnterCritSec request has been made, since the underlying processing of the called function may require processing by another thread and thus cause a > deadlock. !! > > A thread can also execute code without having to give up time slices to other threads in > its process if it requests a priority class that is higher than those of the other threads. A > thread's priority is examined with DosGetInfoBlocks, and changed with DosSetPriority. > > A count is maintained of the number of times DosEnterCritSec is issued without a corresponding DosExitCritSec. The count is incremented by DosEnterCritSec and decremented by DosExitCritSec. > > Normal thread dispatching is not restored until the count is zero. The outstanding > DosEnterCritSec count is maintained in a word. If an overflow occurs, the count is set to > the maximum value, no operation is performed, and the request returns with ERROR_CRITSEC_OVERFLOW. > > If a signal occurs, thread 1 begins execution to process the signal even though another thread in the process has a DosEnterCritSec active. Thread 1 of a process is its initial > thread of execution, not a thread created with DosCreateThread. > > Any processing done by thread 1 to satisfy the signal must not include accessing the > critical resource intended to be protected by DosEnterCritSec. > > There is one exception to the exclusivity of critical sections. If a signal occurs, thread 1 > will be allowed to execute its exception handling code even if another thread in the > same process is in a critical section. For this reason, execption handling code must be > carefully written to avoid performing any operations that might interfere with a thread > in a critical section. > > Note: This function is very powerful and must be used with caution! > > It should be used only in a most cooperative environment where the state of all threads in known. While in the critical section, do not call other compiler runtime or OS/2 functions that could start another thread that it would depend on running before being able to > return. > > DosQueryThreadContext can be used to obtain the context of other threads in the process > once they have been blocked by DosEnterCritSec. > > Calls to DosEnterCritSec() can be nested. Thus, if three calls to DosEnterCritSec() are > issued, three calls to DosExitSec() must be issued to reenable scheduling. > > > ERROR_INVALID_THREADID is returned when an invalid attempt is made to enter a critical section of code in a signal handler or exception handler. > > ERROR_INVALID_THREADID is also returned when a dynamic link library (DLL) routine incorrectly issues DosEnterCritSec. > > Example: > > > /* This example shows how a thread enters and exits a critical section of code. */ > > #define INCL_DOSPROCESS /* Process values */ > #define INCL_DOSERRORS /* Error values */ > #include <os2.h> > #include <stdio.h> > > int main(VOID) > > { > > APIRET rc = NO_ERROR; /* Return code */ > > rc = DosEnterCritSec(); > > if (rc != NO_ERROR) { > > printf("DosEnterCritSec error: return code = %u\n",rc); > return 1; > } > > /***********************************************/ > /* Add critical section code here. While this */ > /* code is running, all other threads are */ > /* stopped. CALL NO LIBRARY OR OS/2 FUNCTIONS */ > /* HERE UNLESS YOU KNOW THEY DO NOT REQUIRE */ > /* ACTION BY ANOTHER THREAD IN THE PROCESS. */ > /***********************************************/ > > rc = DosExitCritSec(); > > if (rc != NO_ERROR) { > > printf("DosExitCritSec error: return code = %u\n",rc); > return 1; > } > > return NO_ERROR; > } > > > 3. DosExitCritSec() > > Syntax: > > Restores normal thread dispatching for the current process. > > #define INCL_DOSPROCESS > #include <os2.h> > > APIRET ulrc; /* Return Code. */ > > ulrc = DosExitCritSec(); > > Prototype: > > APIRET DosExitCritSec(void); > > Parameters: > > ulrc (APIRET) - returns : Return Code. > > DosExitCritSec returns one of the following values: > > 0 NO_ERROR > 309 ERROR_INVALID_THREADID > 485 ERROR_CRITSEC_UNDERFLOW > > Remarks: > > DosExitCritSec is used following DosEnterCritSec to restore normal thread > switching to the threads of a process. > > A count is maintained of the number of times DosEnterCritSec is issued > without a corresponding DosExitCritSec. The count is incremented by > DosEnterCritSec, and decremented by DosExitCritSec. Normal thread > dispatching is not restored until the count is zero. > > If multiple DosEnterCritSec() calls have been issued, then the same number of > DosExitCritSec() calls are required before scheduling actually will be enabled. > > The outstanding count is maintained in a word. If an underflow occurs (the > count is decremented below zero), the count is set to zero, no operation is > performed, and the request returns with ERROR_CRITSEC_UNDERFLOW. > > ERROR_INVALID_THREADID is returned when an invalid attempt is made to > exit a critical section of code in a signal handler or exception handler. > > ERROR_INVALID_THREADID is also returned when a dynamic link library (DLL) > routine incorrectly issues DosExitCritSec. > > > Example: > > See the example concerning DosEnterCritSec() above. > > > > > > > > > > > > > > > >
_, _, _, _, _ _, _,_
(_ | / \ |\ | / \ |_/
, ) | , \ / | \| \ / | \
~ ~~~ ~ ~ ~ ~ ~ ~
Programmed by
Dmitri Maximovich
,
Dmitry I. Platonoff
,
Eugen Kuleshov
.
25.09.99 (c) 1999,
RU/2
. All rights reserved.
Rewritten by
Dmitry Ban
. All rights ignored.