Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

QueueUserWorkItem, beginthread() and C runtime

231 views
Skip to first unread message

lallous

unread,
Mar 10, 2004, 3:20:44 AM3/10/04
to
Hello

1)
The QueueUserWorkItem function queues a work item to a worker thread in the
thread pool.

2)
Warning If you are going to call C run-time routines from a program built
with LIBCMT.LIB, you must start your threads with the _beginthread function.
Do not use the Win32 functions ExitThread and CreateThread. Using
SuspendThread can lead to a deadlock when more than one thread is blocked
waiting for the suspended thread to complete its access to a C run-time data
structure.
The _beginthread function initializes certain C run-time library variables.
This is important only if you use the C run-time library in your threads.


These were excerpts from MSDN.

Now can I use QueueUserWorkItem() and still not have problems outlined in
(2) or I have to write my own thread pool code that uses _beginthread() ?

--
Elias


Ivan Brugiolo [MSFT]

unread,
Mar 10, 2004, 4:19:16 AM3/10/04
to
Which kind of function are you going to execute on the NtDll-Thread-Pool ?
If you have Task-Items that are implicitely or explicitely thread affine,
then you should break this affinity by using the Context param
you provide to the QueueUserWorkItem.
Other than this, there is no reason to re-implement the thread pool
using _beginthreadex().

Naturally it's always nice not to call ExitThread and or SuspendThread
from a Work-Item, since you may be causing process-wide deadlocks.

--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm


"lallous" <lal...@lgwm.org> wrote in message
news:e7rM#jnBEH...@TK2MSFTNGP10.phx.gbl...

lallous

unread,
Mar 10, 2004, 4:26:40 AM3/10/04
to
Hello

I will be using the STL, some C functions and the new/delete operators.

Is that safe?

> > The _beginthread function initializes certain C run-time library
> variables.

What it does exactly and is it safe to use QueueUserworkItem() and skip
beginthread's initialization of certain C run-time library variables?

--
Elias
"Ivan Brugiolo [MSFT]" <ivan...@online.microsoft.com> wrote in message
news:ulF#EDoBEH...@TK2MSFTNGP10.phx.gbl...

Ivan Brugiolo [MSFT]

unread,
Mar 10, 2004, 1:59:55 PM3/10/04
to
The Standard C++ Library containers and algorithms are not thread affine,
so it is NOT thread affine the new/delete implementation
in the system supplied C-Runtime,
so, both of these are sade to use,
and there are indeed many system services that uses them in work-items.

_beginthreadex allocates and initialized the _tiddata structure,
that is a per-thread/per-fiber structure owned by msvcrt.
That structure is initialzied on-demand in threads that don't have the
C-Rutnime
initialized on startup, and it's delete in DllMain(THREAD_DETACH).
_tiddata is used to contain errno, exception handling information,
"file-descriptors",
and quite a few other things with locale and strings.

One thing you may consider doing,
is to NOT let any C++ exception leave the work-item function.
NtDll.dll does not attempt to protect from flying-around exceptions,
and you will soon fall in the "undefined-behavior" land.

If you have Win2003, you can use
c:\>gflags -i YourApp.exe +vrf
to enable rintime verification of boundary condition for your work-item,
such as the fact that a thread cannot own a critical section while leaving a
work-item.

One more gotcha is to not perform an alertable wait on an IO-worker thread
unless you have crystalline clear the re-entrancy contition you are going to
introduce.
For example, the OLEDB provider dor SQL uses a Named-Pipe library form SQL
that dees indeed perform an alertable way, and you have to code accordingly
if you are in a work-item.

--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm


"lallous" <lal...@lgwm.org> wrote in message

news:etKf0IoB...@TK2MSFTNGP09.phx.gbl...

Kirk Ferdmann

unread,
Mar 11, 2004, 4:08:03 AM3/11/04
to
"Ivan Brugiolo [MSFT]" <ivan...@online.microsoft.com> wrote in message
news:eI87gHtB...@TK2MSFTNGP10.phx.gbl...

> The Standard C++ Library containers and algorithms are not thread affine,
> so it is NOT thread affine the new/delete implementation
> in the system supplied C-Runtime,
> so, both of these are sade to use,
> and there are indeed many system services that uses them in work-items.

Well what would you recommend if one needs to use something like strtok?

-Kirk


Ivan Brugiolo [MSFT]

unread,
Mar 11, 2004, 5:14:47 AM3/11/04
to
Not attempt to use the same tokenization saved-data across different
work-item possibly executed in different threads at different times.
The _tiddata does not travel with the Context associated with a work-item.
Things such as queue-ing a work-item from a thread
in the middle of some C++ exception dispatching,
and hoping for such state to be preserved are beyond
what the current implementation is capable.
If you have explicit context to move around, use the Context PVOID pointer.

--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm


"Kirk Ferdmann" <kirk_f...@nospam.hotmail.com> wrote in message
news:8MadnSDERt1...@comcast.com...

Pavel Lebedinsky

unread,
Mar 11, 2004, 9:59:36 PM3/11/04
to
"Kirk Ferdmann" wrote:

> > The Standard C++ Library containers and algorithms are not thread
affine,
> > so it is NOT thread affine the new/delete implementation
> > in the system supplied C-Runtime,
> > so, both of these are sade to use,
> > and there are indeed many system services that uses them in work-items.
>
> Well what would you recommend if one needs to use something like strtok?

I'm a bit lost here. What is the problem we are trying to solve? The
possibility
of memory leaks if threads are not started using CRT functions?

If so then there are two options. First (and best), use the DLL version
of CRT. If you insist on using libcmt, put the code in a DLL (and do not
call
DisableThreadLibraryCalls). The memory will be cleaned up when your
DllMain is called.


Kirk Ferdmann

unread,
Mar 12, 2004, 2:26:59 AM3/12/04
to
"Pavel Lebedinsky" <m_pll ./. hotmail ./. com> wrote in message
news:e8$nO49BE...@tk2msftngp13.phx.gbl...

> I'm a bit lost here. What is the problem we are trying to solve? The
> possibility of memory leaks if threads are not started using CRT
> functions?

I thought that Ivan was implying that since CRT was not initialized for the
threads in the pool, functions that do require _tiddata structure are not
going to work. A little experiment shows that it's not the case. In fact
_getptd method will allocate and initialize the structure when invoked the
first time.

> If so then there are two options. First (and best), use the DLL version
> of CRT. If you insist on using libcmt, put the code in a DLL (and do not
> call
> DisableThreadLibraryCalls). The memory will be cleaned up when your
> DllMain is called.

How about this: _freeptd ( _getptd () ); at the end of the work item?

-Kirk


Ivan Brugiolo [MSFT]

unread,
Mar 12, 2004, 3:51:13 AM3/12/04
to
I said that the C-runtime functions will initialize _tiddata on-demand.
You shoult NOT try to release the C-Runtime private structures on your own.
The thread termination callback (DllMain(THREAD_DETACH))
(and the Fiber-Local-Storage cleanup callback, if the runtime and the OS
supports it)
will do the cleanup when it's the right time.

--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm

"Kirk Ferdmann" <kirk_f...@nospam.hotmail.com> wrote in message

news:TO6dnR9piKk...@comcast.com...

0 new messages