This article was originally posted in my csdn.net blog on 3 Feb,2009.
One of my team member encountered a problem about errno in a multi-threaded environment under AIX.
The program worked well before the introduction of a lower-level component which was mutil-threaded. But now it always exited during the startup process. After debugging we located the problem. The program called function mkdir during startup to create directory and then took corresponding actions according to the return value of mkdir and the value errno. If the return value was -1 and errno was EEXIST, the program thought the directory already existed. But actually the return value was -1 and errno was not EEXIST but 0 when the directory was in existence, so the program exited because it thought the directory could not be created.
The problem occurs just when the multi-threaded component is refered, therefore we can easily have clue to check where the problem is.
The definition of errno in errno.h is like the following:
#if defined(_THREAD_SAFE) || defined(_THREAD_SAFE_ERRNO)
/*
* Per thread errno is provided by the threads provider. Both the extern int
* and the per thread value must be maintained by the threads library.
*/
extern int *_Errno( void );
#define errno (*_Errno())
#else
extern int errno;
#endif /* _THREAD_SAFE || _THREAD_SAFE_ERRNO */
That is to say, errno can be used in multi-threaded environment if either THREAD_SAFE or _THREAD_SAFE_ERRNO is defined. The errno is not an integer but a functional pointer in such case.
But it was still confused because many modules worked well although THREAD_SAFE and _THREAD_SAFE_ERRNO were both not explicitly defined in our programs.
I remembered the pthread.h should be the first included header file in multi-threaded programming because the first code segment in pthread.h is just to define _THREAD_SAFE:
#ifndef _THREAD_SAFE
#define _THREAD_SAFE 1
#endif
Unfortunately many software engineers didn’t pay attention to this issue so that pthread.h is not at the first place in many source files. And it was too difficult for us to modify all files. So our solution was adding -D_THREAD_SAFE in makefile.
No comments:
Post a Comment