线程及进程同步方法分享(一): 线程同步(互斥量)

互斥量的相关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 \n",getpid()); 
	ret = pthread_mutex_lock(&g_stCondMutex);
	printf("pthread_mutex_lock  ret= %d \n", ret); 
	
	ret = pthread_mutex_trylock(&g_stCondMutex);
	printf("pthread_mutex_trylock, ret = %d \n", ret); 

	sleep(15);
}

void * thread_test2(void *arg) {
	bool ret = 0;
	struct timespec u32TSOut;
	unsigned int u32TimeoutInSec=0;
	
	printf(" enter thread_test2  pid= %d \n",getpid()); 
	sleep(2);
	
	if (clock_gettime(CLOCK_REALTIME, &u32TSOut) == -1) //CLOCK_REALTIME  CLOCK_MONOTONIC
	{
		printf("clock_gettime fail1\n");
	}
	printf(" %s, u32TSOut.tv_sec1 = %ld \n",  __FUNCTION__, u32TSOut.tv_sec);
	u32TSOut.tv_sec += 10;  


	ret = pthread_mutex_timedlock(&g_stCondMutex, &u32TSOut);
	printf("pthread_mutex_timedlock, ret = %d \n", ret); 
	if (clock_gettime(CLOCK_REALTIME, &u32TSOut) == -1) //CLOCK_REALTIME  CLOCK_MONOTONIC
	{
		printf("clock_gettime fail2\n");
	}
	printf(" %s, u32TSOut.tv_sec2 = %ld \n",  __FUNCTION__, u32TSOut.tv_sec);

	
	printf(" out thread_test2, ret = %d \n", 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 \n"); 
	return 0;
}

code 运行结果:

$ ./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 test1 and thread test2,  thread test2 wait 期间 thread test1 unlock mutxt, 结果如下:

void * thread_test1(void *arg) {
	int ret = 0;
	struct timespec u32TSOut;
	unsigned int u32TimeoutInSec=0;
	
	printf("enter thread_test1  pid= %d \n",getpid()); 
	ret = pthread_mutex_lock(&g_stCondMutex);
	printf("pthread_mutex_lock  ret= %d \n", ret); 

	
	ret = pthread_mutex_trylock(&g_stCondMutex);
	printf("pthread_mutex_trylock, ret = %d \n", ret); 
	sleep(6);
	ret = pthread_mutex_unlock(&g_stCondMutex);
	
	if (clock_gettime(CLOCK_REALTIME, &u32TSOut) == -1) //CLOCK_REALTIME  CLOCK_MONOTONIC
	{
		printf("clock_gettime fail0\n");
	}
	printf(" %s, u32TSOut.tv_sec0 = %ld \n",  __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 \n",getpid()); 
	sleep(2);
	
	if (clock_gettime(CLOCK_REALTIME, &u32TSOut) == -1) //CLOCK_REALTIME  CLOCK_MONOTONIC
	{
		printf("clock_gettime fail1\n");
	}
	printf(" %s, u32TSOut.tv_sec1 = %ld \n",  __FUNCTION__, u32TSOut.tv_sec);
	u32TSOut.tv_sec += 10;  


	ret = pthread_mutex_timedlock(&g_stCondMutex, &u32TSOut);
	printf("pthread_mutex_timedlock, ret = %d \n", ret); 
	
	if (clock_gettime(CLOCK_REALTIME, &u32TSOut) == -1) //CLOCK_REALTIME  CLOCK_MONOTONIC
	{
		printf("clock_gettime fail2\n");
	}
	printf(" %s, u32TSOut.tv_sec2 = %ld \n",  __FUNCTION__, u32TSOut.tv_sec);

	
	printf(" out thread_test2, EAGAIN = %d \n", EAGAIN ); 
	printf(" out thread_test2, EINVAL = %d \n", EINVAL );
	printf(" out thread_test2, EBUSY   = %d \n", EBUSY   );
	printf(" out thread_test2, ETIMEDOUT = %d \n", 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

你可能感兴趣的:(linux)