目录
一、自由抒发
二、函数介绍
1、pthread_mutex_init
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
2、pthread_mutex_destroy
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
3、pthread_mutexattr_init
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
4、pthread_mutexattr_destroy
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
5、pthread_mutexattr_getpshared
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
6、pthread_mutexattr_setpshared
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
7、pthread_mutexattr_gettype
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
8、pthread_mutexattr_settype
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
9、pthread_mutexattr_getrobust
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
10、pthread_mutexattr_setrobust
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
11、pthread_mutex_consistent
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
12、pthread_mutex_lock
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
13、pthread_mutex_unlock
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
14、pthread_mutex_trylock
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
15、pthread_mutex_timedlock
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
三、如何避免死锁
1、重复加锁
2、互持锁
四、测试与练习
1、部分demo源码
2、编译
3、运行
一、自由抒发
多线程编程时,我们可能需要对一个共享资源进行访问,如果资源是只读的,那便不存在不一致的问题,但共享访问的资源是可读可写的,例如想实现一个生产者消费者模型,那就需要提供一种同步机制,来保障各个线程每次拿到的数据是正确的。最基本的同步方式有:互斥执行、条件同步、栅栏同步。这三种应该对着不同的场景:
名称 | 描述 |
互斥执行 | 两个线程顺序的访问共享资源。 |
条件同步 | 线程必须等待某个事件发生,才能去访问共享资源。 |
栅栏同步 | 控制线程执行过程中的汇合。 |
二、函数介绍
1、pthread_mutex_init
(1)声明
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
(2)作用
初始化互斥锁。
(3)参数
参数名 | 描述 |
mutex | 需要初始化的互斥锁变量。 |
attr | 互斥锁的属性。NULL的话,互斥锁会被初始化为系统默认属性。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
一个互斥变量只能被pthread_mutex_init函数初始化一次,如果初始化多次,有的系统会提示错误,但Linux系统会正常运行,需多注意。
(6)宏
无
2、pthread_mutex_destroy
(1)声明
int pthread_mutex_destroy(pthread_mutex_t *mutex);
(2)作用
销毁互斥锁。
(3)参数
参数名 | 描述 |
mutex | 需要销毁的互斥锁变量。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
无
(6)宏
无
3、pthread_mutexattr_init
(1)声明
int pthread_mutexattr_init(pthread_mutexattr_t *attr);
(2)作用
初始化互斥锁属性。
(3)参数
参数名 | 描述 |
attr | 需要初始化的互斥锁属性变量。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
无
(6)宏
无
4、pthread_mutexattr_destroy
(1)声明
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
(2)作用
销毁互斥锁属性。
(3)参数
参数名 | 描述 |
attr | 需要销毁的互斥锁属性变量。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
无
(6)宏
无
5、pthread_mutexattr_getpshared
(1)声明
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict attr, int *restrict pshared);
(2)作用
获取互斥变量进程共享属性值。
(3)参数
参数名 | 描述 |
attr | 需要获取的互斥锁属性变量。 |
pshared | 获取到的互斥变量进程共享属性值。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
无
(6)宏
见pthread_mutexattr_init函数的相关宏。
6、pthread_mutexattr_setpshared
(1)声明
int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared);
(2)作用
设置互斥变量进程共享属性值。
(3)参数
参数名 | 描述 |
attr | 需要设置的互斥锁属性变量。 |
pshared | 设置的互斥变量进程共享属性值。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
无
(6)宏
宏 | 描述 |
PTHREAD_PROCESS_PRIVATE | 只有同一个进程中的线程使用,默认值。 |
PTHREAD_PROCESS_SHARED | 可以多个进程的线程使用。 |
7、pthread_mutexattr_gettype
(1)声明
int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict attr, int *restrict type);
(2)作用
获取互斥变量类型属性值。
(3)参数
参数名 | 描述 |
attr | 需要获取的互斥锁属性变量。 |
type | 获取到的互斥变量类型属性值。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
无
(6)宏
见pthread_mutexattr_init函数的相关宏。
8、pthread_mutexattr_settype
(1)声明
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
(2)作用
设置互斥变量类型属性值。
(3)参数
参数名 | 描述 |
attr | 需要设置的互斥锁属性变量。 |
type | 设置的互斥变量类型属性值。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
无
(6)宏
宏 | 描述 |
PTHREAD_MUTEX_DEFAULT | 默认类型,标准规定可以是以下任意类型,也可以是完全不同的类型。Linux 3.2.0映射为PTHREAD_MUTEX_NORMAL,FreeBSD 8.0映射为PTHREAD_MUTEX_ERRORCHECK。 |
PTHREAD_MUTEX_NORMAL | 基本类型,无内建的特定错误和死锁检测,但也是最快的一种。 |
PTHREAD_MUTEX_RECURSIVE | 递归类型,允许同一个线程对其解锁之前进行多次加锁,为了释放此变量,需对其解锁相同次数。解锁和加锁次数不同的情况下,不会释放锁。 |
PTHREAD_MUTEX_ERRORCHECK | 提供错误检测功能。效率上比PTHREAD_MUTEX_NORMAL低很多,主要用于调试代码。 |
互斥量类型 | 锁拥有者没有解锁时重复加锁 | 锁未持有者解锁 | 解锁状态重复解锁 |
PTHREAD_MUTEX_DEFAULT | 未知 | 未知 | 未知 |
PTHREAD_MUTEX_NORMAL | 死锁 | 未知 | 未知 |
PTHREAD_MUTEX_RECURSIVE | 允许 | 报错 | 报错 |
PTHREAD_MUTEX_ERRORCHECK | 报错 | 报错 | 报错 |
9、pthread_mutexattr_getrobust
(1)声明
int pthread_mutexattr_getrobust(const pthread_mutexattr_t *__attr, int *__robustness)
;
(2)作用
获取互斥变量健壮属性值。
(3)参数
参数名 | 描述 |
__attr | 需要获取的互斥锁属性变量。 |
__robustness | 获取到的互斥变量健壮属性值。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
无
(6)宏
见pthread_mutexattr_init函数的相关宏。
10、pthread_mutexattr_setrobust
(1)声明
int pthread_mutexattr_setrobust(pthread_mutexattr_t *__attr, int __robustness)
;
(2)作用
设置互斥变量健壮属性值。
(3)参数
参数名 | 描述 |
__attr | 需要设置的互斥锁属性变量。 |
__robustness | 设置的互斥变量健壮属性值。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
无
(6)宏
宏 | 描述 |
PTHREAD_MUTEX_STALLED | 持有互斥锁的进程终止时不需要采取特别的动作,等待互斥锁解锁的程序会被卡住,默认值。 |
PTHREAD_MUTEX_ROBUST | 这个用于处理这样的场景,两个进程都尝试获取互斥锁,第一个进程获取到了锁,在其还没有解锁之前,异常退出了,第二个进程如果使用PTHREAD_MUTEX_STALLED会卡住,而使用PTHREAD_MUTEX_ROBUST,第二进程的pthread_mutex_lock函数会返回EOWNERDEAD,我们可以根据其返回值来恢复互斥锁。 |
11、pthread_mutex_consistent
(1)声明
int pthread_mutex_consistent(pthread_mutex_t *__mutex);
(2)作用
将健壮性互斥锁保护的状态标记为一致。
这个函数需要结合pthread_mutexattr_setrobust一起使用。
这个用于处理这样的场景,两个进程都尝试获取互斥锁,第一个进程获取到了锁,在其还没有解锁之前,异常退出了,第二个进程如果使用PTHREAD_MUTEX_STALLED会卡住,而使用PTHREAD_MUTEX_ROBUST。第二进程的pthread_mutex_lock函数会返回EOWNERDEAD,一般来说这个锁不是本进程或本线程上的锁,是不能进行解锁的,调用pthread_mutex_consistent之后,就可以进行解锁,解决了如何用Xsi Ipc共享内存加多线程互斥锁实现进程间的消费者生产者模型的问题。后面实现了这种组合用法,和大家分享一下。
(3)参数
参数名 | 描述 |
__mutex | 需要设置的互斥锁属性变量。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
无
(6)宏
见pthread_mutexattr_init函数的相关宏。
12、pthread_mutex_lock
(1)声明
int pthread_mutex_lock(pthread_mutex_t *mutex);
(2)作用
对互斥变量进行加锁。
(3)参数
参数名 | 描述 |
mutex | 需要加锁的互斥变量。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
如果是互斥锁是PTHREAD_MUTEX_NORMAL类型,则该函数不会进行死锁检测,重复进行加锁,会导致死锁。
(6)宏
无
13、pthread_mutex_unlock
(1)声明
int pthread_mutex_unlock(pthread_mutex_t *mutex);
(2)作用
对互斥变量进行解锁。
(3)参数
参数名 | 描述 |
mutex | 需要解锁的互斥变量。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
如果是互斥锁是PTHREAD_MUTEX_NORMAL类型,则该函数不会进行死锁检测,重复进行加锁,会导致死锁。
(6)宏
无
14、pthread_mutex_trylock
(1)声明
int pthread_mutex_trylock(pthread_mutex_t *__mutex);
(2)作用
对互斥变量尝试进行加锁。
(3)参数
参数名 | 描述 |
mutex | 需要加锁的互斥变量。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
如果不能立马拿到互斥锁,会返回EBUSY宏。与pthread_mutex_lock不同,不会一直阻塞在那里。
(6)宏
无
15、pthread_mutex_timedlock
(1)声明
int pthread_mutex_timedlock(pthread_mutex_t *__restrict__ __mutex, const struct timespec *__restrict__ __abstime);
(2)作用
对互斥变量进行加锁,在指定时间内未拿到锁返回特定宏。
(3)参数
参数名 | 描述 |
mutex | 需要加锁的互斥变量。 |
__abstime | 指定时间内拿到锁。
|
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
对互斥变量进行加锁,在指定时间内未拿到锁会返回ETIMEDOUT。
(6)宏
无
三、如何避免死锁
1、重复加锁
同一个线程对一个互斥量加锁两次,那么它自身便会陷入死锁状态,如果互斥锁类型属性设置的是PTHREAD_MUTEX_ERRORCHECK便会报错。
2、互持锁
a和b两个线程,1和2两把互斥锁,a拿锁的顺序是1、2,b拿锁的顺序是2、1。就会导致死锁,如果它们拿锁的顺序是一致的,就可以避免这种情况的发生。
四、测试与练习
1、部分demo源码
三个线程对全局变量进行累加,和为18,表示测试正常。
我这边只是对于线程、线程属性、互斥锁、互斥锁属性做了简单封装,方便使用,如果大家感兴趣的话,可以在留言,我后面找一章分享出来。
#include "MyThread.h"#define THRD_ARRAY_LEN 3
#define SUM_VAL (18 / THRD_ARRAY_LEN)int GlobalCnt = 0;void* TestFunc(void* Arg)
{int i;OneThrdMutexSt *Mutex = (OneThrdMutexSt *)Arg;for ( i = 0; i < SUM_VAL; i++){if (THRD_MUTEX_TIMED_LOCK_F(Mutex) == SUCCESS_FLAG){GlobalCnt++;THRD_MUTEX_UNLOCK_F(Mutex);} }THRD_EXIT(NORMAL_FLAG);
}Status main()
{OneThrdMutexSt *Mutex = NULL;OneThrdSt **ThrdArray = (OneThrdSt **)MyMalloc(sizeof(OneThrdSt *) * THRD_ARRAY_LEN);int i;void *ThrdExitState = NULL;OneThrdMutexCreate(&Mutex,PTHREAD_PROCESS_PRIVATE,PTHREAD_MUTEX_ERRORCHECK,PTHREAD_MUTEX_ROBUST,1,0);for ( i = 0; i < THRD_ARRAY_LEN; i++){OneThrdCreate(&(ThrdArray[i]), PTHREAD_CREATE_JOINABLE,PTHREAD_STACK_MIN, ONE_PAGE_MEM_SIZE,TestFunc, Mutex);}for ( i = 0; i < THRD_ARRAY_LEN; i++){ThrdWait(ThrdArray[i]->ThreadId, &ThrdExitState);LogFormat(Debug,"ThrdExitState : %ld.\n",(long)ThrdExitState);OneThrdFree(&(ThrdArray[i]));}OneThrdMutexFree(&Mutex);free(ThrdArray);ThrdArray = NULL;LogFormat(Debug,"GlobalCnt : %d.\n",GlobalCnt);return SUCCESS_FLAG;
}
2、编译
[gbase@czg2 Pthread]$ make clean
rm -rf Test
[gbase@czg2 Pthread]$ make
gcc -Wall -Wextra -O3 -std=gnu11 Test.c -o Test -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/Log/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/Pthread/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/SqQueue/ -L /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/Make/Libs/ -L /usr/lib64/ -l PublicFunction -l Log -l MyThread -l SqQueue
3、运行
[gbase@czg2 Pthread]$ perf stat -e page-faults ./Test
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdMutexAttrInit : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-MutexAttrSetShrd : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-MutexAttrSetType : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-MutexAttrSetRobust : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdMutexInit : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-MutexAttrGetShrd : OK, SharedVal : PTHREAD_PROCESS_PRIVATE.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-MutexAttrGetType : OK, Type : PTHREAD_MUTEX_ERRORCHECK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-MutexAttrGetRobust : OK, Robust : PTHREAD_MUTEX_ROBUST.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdMutexAttrDstry : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-OneThrdMutexCreate : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdAttrInit : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-SetDetachState : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-SetStackSize : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-SetGuardSize : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdCreate : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-GetDetachState : OK, DetachState : PTHREAD_CREATE_JOINABLE.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-GetStackSize : OK, StackSize : 16384.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-GetGuardSize : OK, GuardSize : 4096.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdAttrDestroy : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-OneThrdCreate : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdAttrInit : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-SetDetachState : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-SetStackSize : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-SetGuardSize : OK.
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexUnLock : OK.
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexUnLock : OK.
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexUnLock : OK.
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexUnLock : OK.
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexUnLock : OK.
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexUnLock : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdCreate : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-GetDetachState : OK, DetachState : PTHREAD_CREATE_JOINABLE.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-GetStackSize : OK, StackSize : 16384.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-GetGuardSize : OK, GuardSize : 4096.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdAttrDestroy : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-OneThrdCreate : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdAttrInit : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-SetDetachState : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-SetStackSize : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-SetGuardSize : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdCreate : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-GetDetachState : OK, DetachState : PTHREAD_CREATE_JOINABLE.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-GetStackSize : OK, StackSize : 16384.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-GetGuardSize : OK, GuardSize : 4096.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdAttrDestroy : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-OneThrdCreate : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdWait : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdExitState : 2.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-OneThrdFree : OK.
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexUnLock : OK.
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexUnLock : OK.
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexUnLock : OK.
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexUnLock : OK.
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexUnLock : OK.
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexUnLock : OK.
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexUnLock : OK.
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexUnLock : OK.
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexUnLock : OK.
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexUnLock : OK.
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexUnLock : OK.
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexUnLock : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdWait : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdExitState : 2.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-OneThrdFree : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdWait : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdExitState : 2.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-OneThrdFree : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdMutexDestroy : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-OneThrdMutexFree : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-GlobalCnt : 18.Performance counter stats for './Test':242 page-faults:u 0.003729662 seconds time elapsed0.000000000 seconds user0.004194000 seconds sys