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

线程及进程的同步 可以使用 信号量, 信号的方法。

但实际使用过程中遇到一个难题,就是 sem_timedwait 使用的是绝对时间, 如果timedwait过程中修改系统时间则会出现异常, timeout 提前退出或timeout 到期后还无法退出。

原来的方法: 

线程同步使用pthread_cond+ mutex的方法可以参考如下文章。

https://blog.csdn.net/wys7250578/article/details/46859961

线程同步使用信号量: (如果将信号量设置为进程共享,应该也适用于进程同步,需要研究可行性)

sem_init  //可以设置进程共享。

sem_destroy

sem_post

sem_getvalue

sem_wait

sem_trywait

sem_timedwait

进程同步信号量 需要使用下面接口:

semget

semctl

semop

实际上cond + mutex的方法 可以设置使用相对时间, 同时通过设置属性也可以用于进程间共享。

以这段代码为例, 不论是进程还是线程同步,都可以使用pthread_condattr_setclock(&ca, CLOCK_MONOTONIC);

采用相对时间而不用绝对时间,避免系统时间修改的影响。

同时可以设置cond及mutex的属性为 PTHREAD_PROCESS_SHARED,  这样mutex和cond 可以进程间共享。

但前提是 mutex和cond 必须创建在共享内存, 同时通过测试发现pthread_mutexattr_t、   pthread_condattr_t  可以创建在共享内存,也可以通过临时变量,  下面code是使用临时变量。

 

下面code 只是一个process, 可以通过另外一个process 发signal 

typedef struct _ST_EST_IPC_SHM
{	
	pthread_mutex_t mutex; //40
	pthread_cond_t cond; //48
	//pthread_mutexattr_t
	pthread_condattr_t condattr; //8
	char str[8];
} ST_TEST_IPC_SHM;

static int   giPLATVIUMemId = -1;
static char  g_cPLATshareMem[20] = "PLAT_TEST2_SHM";
static ST_TEST_IPC_SHM  *g_pShareMem = NULL;

 //main

   printf( "[Process A]pid = %d , ppid = %d\n",   getpid(), getppid());
		if( (gpPLATVIUShareMem = ShmCreate( &giPLATVIUMemId, g_cPLATshareMem, 
			sizeof( ST_PLAT_TEST_IPC_SHM ) ) )==  FALSE)	//Have not Create yet...
	
 		 
		g_pShareMem = (ST_PLAT_TEST_IPC_SHM *)(gpPLATVIUShareMem); 
		//g_pShareMem->mutex;


		char teststr2[] = "1234";
		sprintf(g_pShareMem->str, "%s", teststr2);


		pthread_condattr_t ca;  //&(g_pShareMem->condattr)
		pthread_condattr_init(&ca);
		pthread_condattr_setclock(&ca, CLOCK_MONOTONIC);
		pthread_condattr_setpshared(&ca, PTHREAD_PROCESS_SHARED); 
		if( pthread_cond_init( &(g_pShareMem->cond), &ca) == 0 )
		{
			ret = -1;
		}
		pthread_mutexattr_t ma;
		pthread_mutexattr_init(&ma);
		pthread_mutexattr_setpshared(&ma, PTHREAD_PROCESS_SHARED);
		pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST);

		pthread_mutex_init(&(g_pShareMem->mutex), &ma);

		ret = pthread_mutex_lock(&(g_pShareMem->mutex));
		printf("[Process A]pthread_mutex_lock	ret= %d \n", ret); 

		if (clock_gettime(CLOCK_MONOTONIC, &u32TSOut) == -1) //CLOCK_REALTIME  CLOCK_MONOTONIC
		{
			printf("[Process A]clock_gettime fail1\n");
		}
		printf("[Process A] %s, u32TSOut.tv_sec1 = %ld \n",  __FUNCTION__, u32TSOut.tv_sec);
		u32TSOut.tv_sec += 20;  
		if ((ret = pthread_cond_timedwait(&(g_pShareMem->cond), &(g_pShareMem->mutex), &u32TSOut)) == 0)
		{
			ret = 0;
			printf("[Process A] pthread_cond_timedwait return 0. \n");
		}
		else {
			printf("[Process A] pthread_cond_timedwait return %d. \n", ret);
		}

		if (clock_gettime(CLOCK_MONOTONIC, &u32TSOut) == -1) //CLOCK_REALTIME  CLOCK_MONOTONIC
		{
			printf("[Process A]clock_gettime fail2\n");
		}
		printf("[Process A] %s, u32TSOut.tv_sec2 = %ld \n",  __FUNCTION__, u32TSOut.tv_sec);
		
		pthread_mutex_unlock(&(g_pShareMem->mutex));

		sleep(1);
		printf("[Process A] exit\n");
		exit(EXIT_SUCCESS);
    } 

//process B
        ret = pthread_mutex_lock(&(g_pShareMem->mutex));
		pthread_cond_signal( &(g_pShareMem->cond) ) ;
		ret = pthread_mutex_unlock(&(g_pShareMem->mutex));
	

 

你可能感兴趣的:(linux)