将 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;
}
“如果将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进程可访问