What Is a Thread Exit Code

What is a thread exit code?

There actually doesn't seem to be a lot of explanation on this subject apparently but the exit codes are supposed to be used to give an indication on how the thread exited, 0 tends to mean that it exited safely whilst anything else tends to mean it didn't exit as expected. But then this exit code can be set in code by yourself to completely overlook this.

The closest link I could find to be useful for more information is this

Quote from above link:

What ever the method of exiting, the integer that you return from your process or thread must be values from 0-255(8bits). A zero value indicates success, while a non zero value indicates failure. Although, you can attempt to return any integer value as an exit code, only the lowest byte of the integer is returned from your process or thread as part of an exit code. The higher order bytes are used by the operating system to convey special information about the process. The exit code is very useful in batch/shell programs which conditionally execute other programs depending on the success or failure of one.


From the Documentation for GetEXitCodeThread

Important The GetExitCodeThread function returns a valid error code defined by the application only after the thread terminates. Therefore, an application should not use STILL_ACTIVE (259) as an error code. If a thread returns STILL_ACTIVE (259) as an error code, applications that test for this value could interpret it to mean that the thread is still running and continue to test for the completion of the thread after the thread has terminated, which could put the application into an infinite loop.


My understanding of all this is that the exit code doesn't matter all that much if you are using threads within your own application for your own application. The exception to this is possibly if you are running a couple of threads at the same time that have a dependency on each other. If there is a requirement for an outside source to read this error code, then you can set it to let other applications know the status of your thread.

Set thread exit code manually in C#?

.NET threads do not have exit codes. Those are used by the native threads on Windows, but native threads are only used by managed threads, and have no 1:1 correspondence to a given managed thread. The same managed thread can run on multiple native threads and vice versa (though obviously not at the same time). To quote MSDN:

An operating-system ThreadId has no fixed relationship to a managed thread, because an unmanaged host can control the relationship between managed and unmanaged threads. Specifically, a sophisticated host can use the Fiber API to schedule many managed threads against the same operating system thread, or to move a managed thread among different operating system threads.

This of course applies to all resources tied to the native thread - but the runtime does manage the managed resources of a thread, of course; and for unmanaged code calling into managed code, the thread will be kept the same - otherwise interop would be quite impossible.

If you want to add extra information to tasks, try using a higher level of abstraction - e.g. Task. Need to output the status of a task on completion? Add a continuation. Need to check the status of a task you have a reference for? Await it or query the Task object.

Is it possible to return an exit code from a thread in C++?

You'll need to use platform-specific threads instead of std::thread.

In Windows you would use CreateThread. In Visual Studio there is _beginthread and _beginthreadex (use the later only, _beginthead is not recommended), that should be used instead of CreateThread, although currently there's no much difference. When using those functions, you just return exit code from your thread function. Alternatively, call ExitThread or _endthreadex. but this may be not safe, as it will not execute any later code, including destructors of objects in current scope.

How collect thread exit status(using join) when cancelled

If a thread is cancelled (before it has terminated normally), then when you join it, you will receive PTHREAD_CANCELED as the thread's return value / exit status. That macro expands to the actual void * value that is returned, so you can compare the value you receive directly to that to judge whether the thread was cancelled. It generally is not a valid pointer, so you must not try to dereference it.

Example:

    void *status;

// ...

if (pthread_join(t_id, &status) != 0) {
// pthread_join failed
} else if (status == PTHREAD_CANCELED) {
// successfully joined a thread that was cancelled
// 'status' MUST NOT be dereferenced
} else {
// successfully joined a thread that terminated normally
// whether 'status' may be dereferenced or how else it may be
// used depends on the thread
}

It is worth noting that the wording of the Linux manual page is a bit fast and loose. Threads do not have an "exit status" in the sense that processes do, and the actual POSIX specifications do not use the term in the context of threads. For example, the POSIX specifications for pthread_join() say:

On return from a successful pthread_join() call with a non-NULL value_ptr argument, the value passed to pthread_exit() by the terminating thread shall be made available in the location referenced by value_ptr.

That's a bit of a mouthful compared to the Linux wording, but it is chosen to be very precise.

Note also that the choice of type void * here is intentional and useful. It is not merely an obtuse way to package an int. Through such a pointer, a thread can provide access to an object of any type, as may be useful for communicating information about the outcome of its computations. On the other hand, it is fairly common for threads to eschew that possibility and just return NULL. But if a thread did want to provide an integer code that way, then it would most likely provide an intvalue cast to type void *, rather than a pointer to an object of type int containing the chosen value. In that case, one would obtain the value by casting back to int, not by dereferencing the pointer.

Why am I seeing multiple The thread 0x22c8 has exited with code 259 (0x103). messages

From MSDN Documentation:

Remarks

This function returns immediately. If the specified thread has not
terminated and the function succeeds, the status returned is
STILL_ACTIVE. If the thread has terminated and the function succeeds,
the status returned is one of the following values: The exit value
specified in the ExitThread or TerminateThread function. The return
value from the thread function. The exit value of the thread's
process. Important The GetExitCodeThread function returns a valid
error code defined by the application only after the thread
terminates. Therefore, an application should not use STILL_ACTIVE
(259) as an error code. If a thread returns STILL_ACTIVE (259) as an
error code, applications that test for this value could interpret it
to mean that the thread is still running and continue to test for the
completion of the thread after the thread has terminated, which could
put the application into an infinite loop.

So basically it's still checking current thread from time to time.

It seems to be a bug:

http://connect.microsoft.com/VisualStudio/feedback/details/812144/vs2013-reports-incorrect-thread-exit-code

boost::thread exit code?

I don't know that the thread exit code is available as that's operating system specific. You could simulate passing an exit code or result code by doing something like this:

struct callable {
int result;
void operator()()
{
result = 42;
}
};

void process_on_thread() {
callable x;
boost::thread processor(x);

processor.join();
int result = x.result;
}

Cudafy The thread has exited with code 259

Tahnks to Hans Passant who pinted that this is not problem at all and that gpu card should work wihtou problem. I find error in other part of code. So code above works fine.

Exit code of thread in Windows C++

If you want to wait for a thread to exit, just wait on the thread's handle. Once the wait completes you can get the exit code for that thread.

DWORD result = WaitForSingleObject( hThread, INFINITE);

if (result == WAIT_OBJECT_0) {
// the thread handle is signaled - the thread has terminated
DWORD exitcode;

BOOL rc = GetExitCodeThread( hThread, &exitcode);
if (!rc) {
// handle error from GetExitCodeThread()...
}
}
else {
// the thread handle is not signaled - the thread is still alive
}

This example can be extended to waiting for completion of several thread by passing an array of thread handles to WaitForMultipleObjects(). Figure out which thread completed using the appropriate offset from WAIT_OBJECT_0 on the return from WaitForMultipleObjects(), and remove that thread handle from the handle array passed to WaitForMultipleObjects() when calling it to wait for the next thread completion.



Related Topics



Leave a reply



Submit