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

将  pthread_mutex_t  串接在  共享内存,同时 pthread_mutex_t 设置为进程共享属性,可以实现跨进程同步。 

void * ShmCreate( int *iShmId, c8 *pc8Name, u32 u32Shmsize ) 
{
    u32 Key;
	
    Key = Crc32_ComputeBuf(0, 0, 0);
    Key = Crc32_ComputeBuf(Key, (void*) pc8Name, strlen(pc8Name));

    *iShmId = shmget(Key, u32Shmsize, 0666 | IPC_CREAT);
    if (*iShmId == -1) {
        printf("ShmCreate fail!");
        return FALSE;
    }
	printf("ShmCreate iShmId =%d \n", iShmId);	 
    return (void *)shmat(*iShmId, (void *)0, 0);
}

static void *_pstTestCond = NULL;

/// PLAT VIU SHM Memory Function
typedef struct _ST_PLAT_TEST_IPC_SHM
{	
	pthread_mutex_t mutex;;
	char str[8];
} ST_PLAT_TEST_IPC_SHM;


static void *gpPLATVIUShareMem = NULL;

static int   giPLATVIUMemId = -1;
static char  g_cPLATshareMem[20] = "PLAT_TEST_SHM";
static ST_PLAT_TEST_IPC_SHM  *g_pShareMem = NULL;
//static pthread_mutex_t g_mutex = NULL;

int itest = 888;

int  main( void ) 
{ 
	static void *_pstTestCond = NULL;
	int ret = -1;
	struct timespec u32TSOut;
	
	TD_OS_Init();
	if(_pstTestCond == NULL)
	{
		_pstTestCond = TD_OS_MutexCondCreate(NULL);
		if(_pstTestCond == NULL)
		{
			printf( "TD_OS_MutexCondCreate err.\n" );;
		}
	}

	pid_t child = 2;// fork();
    if ( child == -1 )     
    {
    	printf( "fork err.\n" );
		exit(EXIT_FAILURE);
    } 
	else if ( child == 2 )     // this is the child process
    {
    	printf( "in child process.\n" );
  		printf("\tchild pid = %d\n",  getpid());  
		printf("\tchild ppid = %d\n",  getppid()); 


		if( (gpPLATVIUShareMem = ShmCreate( &giPLATVIUMemId, g_cPLATshareMem, sizeof( ST_PLAT_TEST_IPC_SHM ) ) )==  FALSE)	//Have not Create yet...
		{
			printf("[parent]ShmCreate return false!!! \r\n");
		}
		else
		{
			printf("[parent]ShmCreate returen valid shamem!\r\n");
		}
 		 
		g_pShareMem = (ST_PLAT_TEST_IPC_SHM *)(gpPLATVIUShareMem); 
		//g_pShareMem->mutex;

		
		char teststr[] = "abcd";
		sprintf(g_pShareMem->str, "%s", teststr);
		printf("itest = %d\n", itest); 
		itest = 999;

		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("pthread_mutex_lock	ret= %d \n", ret); 
		sleep(120);
		//ret = pthread_mutex_unlock(&(g_pShareMem->mutex));
		printf("child process unlock mutex\n");
		sleep(1);
		printf("child process exit\n");
		exit(EXIT_SUCCESS);
    } 
	else { //parent process
		printf( "[parent]in parent process.\n" );
		printf("[parent]parent pid = %d \n",getpid());  
        printf("[parent]parent ppid = %d \n",getppid()); 
		if( (gpPLATVIUShareMem = ShmCreate( &giPLATVIUMemId, g_cPLATshareMem, sizeof( ST_PLAT_TEST_IPC_SHM ) ) )==	FALSE)	//Have not Create yet...
		{
			printf("[parent]ShmCreate return false!!! \r\n");
		}
		else
		{
			printf("[parent]ShmCreate returen valid shamem!\r\n");
		}
		
		g_pShareMem = (ST_PLAT_TEST_IPC_SHM *)(gpPLATVIUShareMem); 
		
		printf("[parent]g_pstr: %s \n", g_pShareMem->str);

		printf("[parent]itest = %d\n", itest); 

		ret = pthread_mutex_trylock(&(g_pShareMem->mutex));
		printf("[parent]pthread_mutex_trylock, ret = %d \n", ret); 

		if (clock_gettime(CLOCK_REALTIME, &u32TSOut) == -1) //CLOCK_REALTIME  CLOCK_MONOTONIC
		{
			printf("[parent]clock_gettime fail1\n");
		}
		printf("[parent] %s, u32TSOut.tv_sec1 = %ld \n",  __FUNCTION__, u32TSOut.tv_sec);
		u32TSOut.tv_sec += 35;  

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

		printf("[parent]parent process exit\n"); 
	}
	exit(EXIT_SUCCESS);  
	return 0;
} 
  • 今天有空玩了一下 mutex创建再共享内存并设置进程间共享, 发现真的可以这样做,  但同样存在昨天测试反馈的问题

“如果将date 设置比目前时间早,  timeout 无法退出,  但如果设置比当前时间迟,  timeout还是正常”

[17:17:59]/media/sda # ./testmutex11 &

[17:17:59]/media/sda #  TD_OS_Init, In

[17:17:59] TD_OS_Init, Out

[17:17:59] TD_OS_MutexCondCreate, In

[17:17:59]in child process.

[17:17:59]        child pid = 2262

[17:17:59]        child ppid = 2029

[17:17:59]TD_OS_SysVShmCreate iShmId =139692

[17:17:59][parent]TD_OS_IPCShmCreate returen valid shamem! //获取到共享内存

[17:17:59]itest = 888

[17:17:59]pthread_mutex_lock      ret= 0  //设置mutex的属性为进程共享,同时lock mutex , 然后sleep 121 秒后退出。

[17:17:59]

[17:18:02]/media/sda # ./testmutex22  &

[17:18:02]/media/sda #  TD_OS_Init, In

[17:18:02] TD_OS_Init, Out

[17:18:02] TD_OS_MutexCondCreate, In

[17:18:02][parent]in parent process.

[17:18:02][parent]parent pid = 2264

[17:18:02][parent]parent ppid = 2029

[17:18:02]TD_OS_SysVShmCreate iShmId =139692

[17:18:02][parent]TD_OS_IPCShmCreate returen valid shamem! //获取到共享内存

[17:18:02][parent]g_pstr: abcd

[17:18:02][parent]itest = 888

[17:18:02][parent]pthread_mutex_trylock, ret = 16  //先尝试trylock, 的确返回16错误代码,表示此mutex已经是lock状态, 注意这里不能再重新设置mutex的属性为进程共享, 否则会unlock mutex;

[17:18:02][parent] main, u32TSOut.tv_sec1 = 1543881911  //等待前先打印下时间

[17:18:02]

[17:18:07]/media/sda # date -s 2018-12-02  //之前时间是2018-12-04. 手动修改为旧时间

[17:18:07]Sun Dec  2 00:00:00 UTC 2018

[17:18:08]/media/sda #

[17:19:59]/media/sda # child process exit

[17:20:00][parent]pthread_mutex_timedlock, ret = 130  

 

//正常情况下, 需要一天后才会timeout, 121秒后([17:17:59]~ [17:20:00] timeout了, 是因为第一个进行等待121秒后就退出, 退出时会主动unlock mutex

[17:20:00][parent] main, u32TSOut.tv_sec2 = 1543708912

[17:20:00][parent]parent process exit

[17:20:16]

[17:20:17]/media/sda #

 

 

 

 

https://linux.die.net/man/3/pthread_condattr_setpshared 

pthread_condattr_getpshared, pthread_condattr_setpshared - get and set the process-shared condition variable attributes

感觉通过此API 页可以将condition share进程可访问

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值