スレッドおよびプロセス同期方法の共有(一):スレッド同期(反発量)

5841 ワード

反発量に関するAPI://int pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);//int pthread_mutex_destroy (pthread_mutex_t *mutex);//int pthread_mutex_trylock (pthread_mutex_t *mutex);//int pthread_mutex_lock (pthread_mutex_t *mutex);//int pthread_mutex_timedlock (pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);//int pthread_mutex_unlock (pthread_mutex_t *mutex);
 #include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include  
#include 
static void *_pstTestCond = NULL;

//static pthread_mutex_t g_stCondMutex = PTHREAD_MUTEX_INITIALIZER;
//static pthread_condattr_t g_stCondattr;
void * thread_test1(void *arg) {
	bool ret = 0;
	struct timespec u32TSOut;
	unsigned int u32TimeoutInSec=0;
	
	printf("enter thread_test1  pid= %d 
",getpid()); ret = pthread_mutex_lock(&g_stCondMutex); printf("pthread_mutex_lock ret= %d
", ret); ret = pthread_mutex_trylock(&g_stCondMutex); printf("pthread_mutex_trylock, ret = %d
", ret); sleep(15); } void * thread_test2(void *arg) { bool ret = 0; struct timespec u32TSOut; unsigned int u32TimeoutInSec=0; printf(" enter thread_test2 pid= %d
",getpid()); sleep(2); if (clock_gettime(CLOCK_REALTIME, &u32TSOut) == -1) //CLOCK_REALTIME CLOCK_MONOTONIC { printf("clock_gettime fail1
"); } printf(" %s, u32TSOut.tv_sec1 = %ld
", __FUNCTION__, u32TSOut.tv_sec); u32TSOut.tv_sec += 10; ret = pthread_mutex_timedlock(&g_stCondMutex, &u32TSOut); printf("pthread_mutex_timedlock, ret = %d
", ret); if (clock_gettime(CLOCK_REALTIME, &u32TSOut) == -1) //CLOCK_REALTIME CLOCK_MONOTONIC { printf("clock_gettime fail2
"); } printf(" %s, u32TSOut.tv_sec2 = %ld
", __FUNCTION__, u32TSOut.tv_sec); printf(" out thread_test2, ret = %d
", ret); } int main( void ) { pthread_t thread1, thread2; char pthread1[] = "thread_test1"; char pthread2[] = "thread_test2"; TD_OS_Init(); pthread_create(&thread1, NULL, thread_test1, pthread1); pthread_create(&thread2, NULL, thread_test2, pthread2); sleep(20); printf(" main process exit
"); return 0; }

コード実行結果:
$ ./test    TD_OS_Init, In   TD_OS_Init, Out  enter thread_test1  pid= 49332  pthread_mutex_lock  ret= 0  pthread_mutex_trylock, ret = 16   enter thread_test2  pid= 49332   thread_test2, u32TSOut.tv_sec1 = 1549095172  pthread_mutex_timedlock, ret = 110   thread_test2, u32TSOut.tv_sec2 = 1549095182   main process exit 
エラーコードの値については、#include
EAGAIN = 11  EINVAL = 22  EDEADLK  = 35  ETIMEDOUT = 110 
タイムアウト終了をブロックする必要がある場合はpthread_を使用します.mutex_timedlockですが、このインタフェースは絶対時間しかかかりません.システム時間がwait中に変更された場合、
異常が発生します. 
資料を調べると、mutexが相対時間を使用できるように設定することはできません(linux system timeの変更の影響を受けません)
https://exceptionshub.com/clock_monotonic-and-pthread_mutex_timedlock-pthread_cond_timedwait.html 
https://linux.die.net/man/3/pthread_mutex_timedlock 
thread test 1 and thread test 2、thread test 2 wait期間thread test 1 unlock mutxtを変更します.結果は次のとおりです.
void * thread_test1(void *arg) {
	int ret = 0;
	struct timespec u32TSOut;
	unsigned int u32TimeoutInSec=0;
	
	printf("enter thread_test1  pid= %d 
",getpid()); ret = pthread_mutex_lock(&g_stCondMutex); printf("pthread_mutex_lock ret= %d
", ret); ret = pthread_mutex_trylock(&g_stCondMutex); printf("pthread_mutex_trylock, ret = %d
", ret); sleep(6); ret = pthread_mutex_unlock(&g_stCondMutex); if (clock_gettime(CLOCK_REALTIME, &u32TSOut) == -1) //CLOCK_REALTIME CLOCK_MONOTONIC { printf("clock_gettime fail0
"); } printf(" %s, u32TSOut.tv_sec0 = %ld
", __FUNCTION__, u32TSOut.tv_sec); } void * thread_test2(void *arg) { int ret = 0; struct timespec u32TSOut; unsigned int u32TimeoutInSec=0; printf(" enter thread_test2 pid= %d
",getpid()); sleep(2); if (clock_gettime(CLOCK_REALTIME, &u32TSOut) == -1) //CLOCK_REALTIME CLOCK_MONOTONIC { printf("clock_gettime fail1
"); } printf(" %s, u32TSOut.tv_sec1 = %ld
", __FUNCTION__, u32TSOut.tv_sec); u32TSOut.tv_sec += 10; ret = pthread_mutex_timedlock(&g_stCondMutex, &u32TSOut); printf("pthread_mutex_timedlock, ret = %d
", ret); if (clock_gettime(CLOCK_REALTIME, &u32TSOut) == -1) //CLOCK_REALTIME CLOCK_MONOTONIC { printf("clock_gettime fail2
"); } printf(" %s, u32TSOut.tv_sec2 = %ld
", __FUNCTION__, u32TSOut.tv_sec); printf(" out thread_test2, EAGAIN = %d
", EAGAIN ); printf(" out thread_test2, EINVAL = %d
", EINVAL ); printf(" out thread_test2, EBUSY = %d
", EBUSY ); printf(" out thread_test2, ETIMEDOUT = %d
", ETIMEDOUT ); } $ ./test TD_OS_Init, In TD_OS_Init, Out enter thread_test1 pid= 83523 pthread_mutex_lock ret= 0 pthread_mutex_trylock, ret = 16 // EBUSY, already locked enter thread_test2 pid= 83523 thread_test2, u32TSOut.tv_sec1 = 1549095624 thread_test1, u32TSOut.tv_sec2 = 1549095628 pthread_mutex_timedlock, ret = 0 //lock mutex success thread_test2, u32TSOut.tv_sec2 = 1549095628 out thread_test2, EAGAIN = 11 out thread_test2, EINVAL = 22 out thread_test2, EBUSY = 16 out thread_test2, ETIMEDOUT = 110 main process exit

ついでに接続をコレクションします.https://blog.csdn.net/okiwilldoit/article/details/78487507