counts on an implementation Jailing to detect any error. Do not lock a mutex in one thread and unlock it in another thread, for example, even if you are sure that the error won't be reported — use a semaphore instead, which has no 'ownership' semantics.

All mutexes, regardless of type, are created using pthread_mutex_init, destroyed using pthread_mutex_destroy, and manipulated using pthread_mutex_ lock, pthread_mutex_unlock, and pthread_mutex_trylock.

Normal mutexes will usually be the fastest implementation possible for the machine, but will provide the least error checking.

Recursive mutexes are primarily useful for converting old code where it is difficult to establish clear boundaries of synchronization, for example, when you must call a function with a mutex locked and the function you call — or some function it calls — may need to lock the same mutex. I have never seen a situation where recursive mutexes were required to solve a problem, but I have seen many cases where the alternate (and usually 'better') solutions were impractical. Such situations frequently lead developers to create recursive mutexes, and it makes more sense to have a single implementation available to everyone. (But your code will usually be easier to follow, and perform better, if you avoid recursive mutexes.)

Errorcheck mutexes were devised as a debugging tool, although less intrusive debugging tools (where available) can be more powerful. To use errorcheck mutexes you must recompile code to turn the debugging feature on and off. It is far more useful to have an external option to force all mutexes to record debugging data. You may want to use errorcheck mutexes in final 'production' code, of course, to detect serious problems early, but be aware that errorcheck mutexes will almost always be much slower than normal mutexes due to the extra state and checking.

Default mutexes allow each implementation to provide the mutex semantics the vendor feels will be most useful to the target audience. It may be useful to make errorcheck mutexes the default, for example, to improve the threaded debugging environment of a system. Or the vendor may choose to make normal mutexes the default to give most programs the benefit of any extra speed.

| pthread_mutexaftr_gettype

int pthread_mutexattr_gettype (

const pthread_mutexattr_t *attr,

int *type);

Specify the type of mutexes created with attr.

type

Unspecified type.

Basic mutex, with no error

checking.

PTHREAD_MUTEX_RECURSIVE Thread can relock a mutex it

owns.

PTHREAD_MUTEX_ERRORCHECK Checks for usage errors.

References: 3.2,5.2.1,10.1.2

Errors: [EINVAL] type invalid.

[EINVAL] attr invalid.

Hint: Normal mutexes will usually be fastest; errorcheck mutexes are use-

ful for debugging; recursive mutexes can be useful for making old interfaces thread- safe.

PTHREAD_MUTEX_DEFAULT

PTHREAD_MUTEX_NORMAL

pthread_mutexattr_settype

int pthread_mutexattr_settype (

pthread_mutexattr_t int

*attr, type);

Determine the type of mutexes created with attr.

type

PTHREAD_MUTEX_DEFAULT Unspecified type.

PTHREAD_MUTEX_NORMAL

Basic mutex, with no error checking.

PTHREAD_MUTEX_RECURSIVE Thread can relock a mutex it

owns.

PTHREAD_MUTEX_ERRORCHECK Checks for usage errors.

References: 3.2,5.2.1,10.1.2

Errors: [EINVAL] type invalid.

[EINVAL] attr invalid.

Hint: Normal mutexes will usually be fastest; errorcheck mutexes are use-

ful for debugging; recursive mutexes can be useful for making old interfaces thread- safe.

10.1.3 Set concurrency level

When you use Pthreads implementations that schedule user threads onto some smaller set of kernel entities (see Section 5.6.3), it may be possible to have ready user threads while all kernel entities allocated to the process are busy.

Some implementations, for example, 'lock' a kernel entity to a user thread that blocks in the kernel, until the blocking condition, for example an I/O request, is completed. The system will create some reasonable number of kernel execution entities for the process, but eventually the pool of kernel entities may become exhausted. The process may be left with threads capable of performing useful work for the application, but no way to schedule them.

The pthread_setconcurrency function addresses this limitation by allowing the application to ask for more kernel entities. If the application designer realizes that 10 out of 15 threads may at any time become blocked in the kernel, and it is important for those other 5 threads to be able to continue processing, then the application may request that the kernel supply 15 kernel entities. If it is important that at least 1 of those 5 continue, but not that all continue, then the application could request the more conservative number of 11 kernel entities. Or if it is OK for all threads to block once in a while, but not often, and you know that only rarely will more than 6 threads block at any time, the application could request 7 kernel entities.

The pthread_setconcurrency function is a hint, and implementations may ignore it or modify the advice. You may use it freely on any system that conforms to the UNLX98 brand, but many systems will do nothing more than set a value that is returned by pthread_getconcurrency. On Digital UNIX, for example, there is no need to set a fixed concurrency level, because the kernel mode and user mode schedulers cooperate to ensure that ready user threads cannot be prevented from running by other threads blocked in the kernel.

pthread_getconcurrency

int pthread_getconcurrency ();

Returns the value set by a previous pthread_setconcurrency call. If there have been no previous calls to pthread_setconcurrency, returns 0 to indicate that the implementation is maintaining the concurrency level automatically.

References: 5.6.3, 10.1.3 Errors: none.

Hint: Concurrency level is a hint. It may be ignored by any implementa-

tion, and will be ignored by an implementation that does not need it to ensure

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату
×