Wednesday, November 23, 2005

Простенькая программка: #include <stdio...

Простенькая программка:




#include <stdio.h>

#include <pthread.h>

#include <time.h>



int MTXTYPE;



int rv;



void printresult(const char* what)

{

printf("%s: %d\n", what, rv);

}



int main(void)

{

#ifdef MTXRECURSIVE

MTXTYPE = PTHREAD_MUTEX_RECURSIVE;

#elif defined MTXERRCHECK

MTXTYPE = PTHREAD_MUTEX_ERRORCHECK;

#else

----- THIS WILL CAUSE ERROR -----

#endif

printf("mutex type: %d\n", MTXTYPE );



pthread_mutex_t mtx;

pthread_mutexattr_t attr;



rv = pthread_mutexattr_init(&attr);

printresult("pthread_mutexattr_init");

rv = pthread_mutexattr_settype(&attr, MTXTYPE);

printresult("pthread_mutexattr_settype");

rv = pthread_mutex_init(&mtx, &attr);

printresult("pthread_mutex_init");



rv = pthread_mutex_lock(&mtx);

printresult("pthread_mutex_lock");

rv = pthread_mutex_trylock(&mtx);

printresult("pthread_mutex_trylock");

rv = pthread_mutex_lock(&mtx);

printresult("pthread_mutex_lock");





rv = pthread_mutex_unlock(&mtx);

printresult("pthread_mutex_unlock");

rv = pthread_mutex_destroy(&mtx);

printresult("pthread_mutex_destroy");

rv = pthread_mutexattr_destroy(&attr);

printresult("pthread_mutexattr_destroy");



return 0;

}





Компилирую на двух машинах:

Первая:

[rezndmi@goldtpus17 /home/rezndmi/test/pthread] uname -a

SunOS goldtpus17 5.8 Generic_117350-25 sun4u sparc SUNW,Netra-T12




Вторая:

[rezndmi@goldtpus22 /home/rezndmi/tests]$ uname -a

Linux goldtpus22 2.4.21-251-smp #1 SMP Thu Sep 23 17:22:54 UTC 2004 i686 unknown

(для второй меняю PTHREAD_MUTEX_XXX на PTHREAD_MUTEX_XXX_NP , что тоже самое, что по хидеру, что по логике)




На первой машине:

[rezndmi@goldtpus17 /home/rezndmi/test/pthread] CC -DMTXRECURSIVE pt1.c -o mtxrec

[rezndmi@goldtpus17 /home/rezndmi/test/pthread] CC -DMTXERRCHECK pt1.c -o errchk

[rezndmi@goldtpus17 /home/rezndmi/test/pthread] ./mtxrec

mutex type: 4

pthread_mutexattr_init: 0

pthread_mutexattr_settype: 0

pthread_mutex_init: 0

pthread_mutex_lock: 0

pthread_mutex_trylock: 0

pthread_mutex_lock: 0

pthread_mutex_unlock: 0

pthread_mutex_destroy: 0

pthread_mutexattr_destroy: 0

[rezndmi@goldtpus17 /home/rezndmi/test/pthread] ./errchk

mutex type: 2

pthread_mutexattr_init: 0

pthread_mutexattr_settype: 0

pthread_mutex_init: 0

pthread_mutex_lock: 0

pthread_mutex_trylock: 0

pthread_mutex_lock: 0

pthread_mutex_unlock: 0

pthread_mutex_destroy: 0

pthread_mutexattr_destroy: 0




На второй машине:

[rezndmi@goldtpus22 /home/rezndmi/tests]$ ./lmtxrec

mutex type: 1

pthread_mutexattr_init: 0

pthread_mutexattr_settype: 0

pthread_mutex_init: 0

pthread_mutex_lock: 0

pthread_mutex_trylock: 0

pthread_mutex_lock: 0

pthread_mutex_unlock: 0

pthread_mutex_destroy: 16

pthread_mutexattr_destroy: 0

[rezndmi@goldtpus22 /home/rezndmi/tests]$ ./lmtxerr

mutex type: 2

pthread_mutexattr_init: 0

pthread_mutexattr_settype: 0

pthread_mutex_init: 0

pthread_mutex_lock: 0

pthread_mutex_trylock: 16

pthread_mutex_lock: 35

pthread_mutex_unlock: 0

pthread_mutex_destroy: 0

pthread_mutexattr_destroy: 0




Это как понимать.



Вдобавок, выдаржка из man (3) pthread_XXX :





pthread_mutex_lock()

...

If the mutex type is PTHREAD_MUTEX_NORMAL, deadlock detec-

tion is not provided. Attempting to relock the mutex causes

deadlock. If a thread attempts to unlock a mutex that it has

not locked or a mutex that is unlocked, undefined behavior

results.



If the mutex type is PTHREAD_MUTEX_ERRORCHECK, then error

checking is provided. If a thread attempts to relock a mutex

that it has already locked, an error will be returned. If a

thread attempts to unlock a mutex that it has not locked or

a mutex which is unlocked, an error will be returned.



If the mutex type is PTHREAD_MUTEX_RECURSIVE, then the

mutex maintains the concept of a lock count. When a thread

successfully acquires a mutex for the first time, the lock

count is set to 1. Every time a thread relocks this mutex,

the lock count is incremented by one. Each time the thread

unlocks the mutex, the lock count is decremented by one.

When the lock count reaches 0, the mutex becomes available

for other threads to acquire. If a thread attempts to

unlock a mutex that it has not locked or a mutex that is

unlocked, an error will be returned.

...

The pthread_mutex_trylock() function is identical to

pthread_mutex_lock() except that if the mutex object refer-

enced by mutex is currently locked (by any thread, including

the current thread), the call returns immediately.



1 comment:

  1. dbmostpus124> gcc -DMTXRECURSIVE pthread.c -lpthread
    dbmostpus124> ./a.out
    mutex type: 1
    pthread_mutexattr_init: 0
    pthread_mutexattr_settype: 0
    pthread_mutex_init: 0
    pthread_mutex_lock: 0
    pthread_mutex_trylock: 0
    pthread_mutex_lock: 0
    pthread_mutex_unlock: 0
    pthread_mutex_destroy: 16
    pthread_mutexattr_destroy: 0
    dbmostpus124> gcc -DMTXERRCHECK pthread.c -lpthread
    dbmostpus124> ./a.out
    mutex type: 2
    pthread_mutexattr_init: 0
    pthread_mutexattr_settype: 0
    pthread_mutex_init: 0
    pthread_mutex_lock: 0
    pthread_mutex_trylock: 16
    pthread_mutex_lock: 35
    pthread_mutex_unlock: 0
    pthread_mutex_destroy: 0
    pthread_mutexattr_destroy: 0
    dbmostpus124> uname -a
    Linux dbmostpus124 2.4.19-64GB-SMP #1 SMP Wed May 21 18:11:18 UTC 2003 i686 unknown

    ReplyDelete