With the signal processing program and thread, multiple control threads may potentially call the same function at the same time.
If a function can be safely called by multiple threads at the same time, it is calledThread Security. All functions defined in Single UNIX Specification are thread-safe except those listed in Table 12-5. In addition, the ctermid and tmpnam functions cannot guarantee thread safety when passing in null pointers by parameters. Similarly, the wcrtomb and wcsrtombs functions do not guarantee thread safety if the mbstate_t parameter is a null pointer.
Functions that do not guarantee thread security in Table 12-5 POSIX.1 (this table is from the Third Edition)
Ftrylockfile (FILE * flockfile (FILE * funlockfile (FILE * fp );
Although standard I/O routines may be implemented in thread-safe mode from the perspective of their internal data structures, but sometimes it is very useful to open the lock to the application. This allows applications to combine multiple calls to standard I/O functions into atomic sequences. Of course, when processing multiple FILE objects, pay attention to possible deadlocks and sort all locks carefully.
If both the standard I/O routines obtain their respective locks, the performance will be severely degraded when a single-character I/O operation is performed. In this case, you need to read or write each character to obtain and release the lock. To avoid this overhead, there is a character-based standard I/O routine without locking the version.
#include <stdio.h> getchar_unlocked( getc_unlocked(FILE * putchar_unlocked( putc_unlocked( c, FILE *
Do not call these four functions unless they are surrounded by calls of flockfile (or ftrylockfile) and funlockfile, they cause unexpected results (that is, problems caused by non-synchronous data access by multiple control threads ).
Once the FILE object is locked, these functions can be called multiple times before the lock is released. In this way, the overhead of adding and unlocking can be apportioned on multiple data reads and writes.
Instance
The program list 12-3 shows a possible implementation of getenv (http://www.cnblogs.com/nufangrensheng/p/3508319.html. Because all the strings returned by the getenv call thread are stored in the same static buffer, this version is not reentrant. If two threads call this function at the same time, they will see inconsistent results.
Program list 12-3 Non-reentrant versions of getenv
#include <limits.h><signal.h> ** * *=(i = ; environ[i] != NULL; i++((strncmp(name, environ[i], len) == ) &&== &environ[i][len+
In the program list 12-4, the reentrant version of getenv is given. This version is named getenv_r. It uses the pthread_once function to ensure that each process calls the thread_init function only once.
Program list 12-4 reentrant (thread-safe) version of getenv
#include <.h><errno.h><pthread.h><stdlib.h> ** pthread_once_t init_done = &&&env_mutex, && *name, *buf, &=&(i = ; environ[i][len] != NULL; i++((strncmp(name, environ[i], len) == ) &&== = strlen(&environ[i][len+(olen >=&&environ[i][len+&(&
To make getenv_r reentrant, you need to change the interface. The caller must provide a buffer, so that each thread can use a different buffer to avoid interference from other threads. However, note that this is not enough to make getenv_r thread-safe. To make getenv_r thread-safe, you need to protect the environment from being modified when searching for the request string. We can use mutex to serialize access to the Environment list through the getenv_r and putenv functions.
Read/write locks can be used to allow multiple concurrent accesses to getenv_r, but the increase in concurrency may not greatly improve the program performance. There are two reasons: first, the Environment list is usually not very long, so the list does not need to occupy the mutex for a long time. Second, the call to getenv and putenv is not frequent, therefore, improving their performance will not significantly affect the overall performance of the program.
Even if you change getenv_r to thread-safe, it does not mean that it can be reentrant to the signal processing program. If a non-recursive mutex is used, a deadlock may occur when the thread calls getenv_r from the signal processing program. If the signal processing program interrupts the thread when the thread executes getenv_r, because the locked env_mutex is occupied, other threads attempt to lock the mutex will be blocked, eventually, the thread enters the Deadlock State. Therefore, recursive mutex must be used to prevent other threads from changing the data structure currently being viewed, and also prevent deadlocks from signal processing programs. The problem is that the pthread function does not guarantee the safety of asynchronous signals. Therefore, the pthread function cannot be used by other functions to ensure the safety of asynchronous signals.
This blog is excerpted from advanced programming for UNIX environments (version 2) and used only for personal learning records. For more information about this book, see:Http://www.apuebook.com/.