目录
一、多线程相关文章链接
二、自由抒发
1、自旋锁
2、屏障
三、函数介绍
1、pthread_spin_init
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
2、pthread_spin_destroy
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
3、pthread_spin_lock
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
4、pthread_spin_trylock
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
5、pthread_spin_unlock
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
6、pthread_barrier_init
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
7、pthread_barrier_destroy
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
8、pthread_barrierattr_init
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
9、pthread_barrierattr_destroy
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
11、pthread_barrier_wait
(1)声明
(2)作用
(3)参数
(4)返回值
(5)注意点
(6)宏
四、锁测试验证
1、互斥锁测试Demo
2、自旋锁测试Demo
3、编译
4、互斥锁测试
5、自旋锁测试
6、总结
五、屏障测试验证
1、Demo
2、编译
3、测试
一、多线程相关文章链接
1、《Unix环境高级编程-学习-06-多线程之创建、销毁、属性获取和设置》
2、《Unix环境高级编程-学习-07-多线程之互斥锁》
二、自由抒发
1、自旋锁
自旋锁的表现形式与互斥锁类似,拿不到锁会阻塞,但他们阻塞的原理却不同。举例说明:有10个人(核)每个人手上有一把假的钥匙,同时去换一把真的钥匙,拿到真钥匙的人可以开始自己的事情,其中一个人(核)用假钥匙换到真钥匙,其余的9个人(核)就一直和假钥匙交换,不能做其他事情,相当于在浪费CPU资源,而互斥锁拿不到锁,这个进程进入休眠状态,人(核)可以先去做其他事情,不会浪费太多CPU资源(有一个进程状态切换的消耗)。如果你的程序在访问临界资源的时间非常短,短暂的自旋资源消耗小于进程状态切换的消耗,我们就可以用自旋锁来实现互斥。
2、屏障
屏障是用户协调多线程并行工作的同步机制,类似于pthread_join等待所有线程结束,屏障只是少了结束这一步,线程还是可以继续使用。
例如给你一个这样的有向无环图,左上角是任务的起点,右下角是任务的终点,我们需要怎么去协同计算呢。
如果是单线程的我们通过拓扑排序得到的节点访问顺序是A->B->C->D->E->F->G->H->I->J->J->L,拓扑排序的相关方法可以参考之前的博客《数据结构与算法基础-学习-28-图之拓扑排序》,如果使用多线程的方法呢,首先主线程完成任务A,启动两个线程同时去做B和E,因为他们的前置条件任务A已经完成,所以可以平行,例如B先做完,需要等E做完,才能开三个线程同时去做C、F、I,那这个B等E完成,之后再去做其他事,这个同步行为就是屏障。
三、函数介绍
1、pthread_spin_init
(1)声明
int pthread_spin_init(pthread_spinlock_t *__lock, int __pshared);
(2)作用
初始化自旋锁。
(3)参数
参数名 | 描述 |
__lock | 需要初始化的自旋锁变量。 |
__pshared | 自旋锁的共享属性。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
如果pthread_spin_init()调用已经初始化过的自旋锁,结果是未定义。
如果在未初始化的情况下使用旋转锁,则结果是未定义的。
(6)宏
宏 | 描述 |
PTHREAD_PROCESS_PRIVATE | 只有同一个进程中的线程使用,默认值。 |
PTHREAD_PROCESS_SHARED | 可以多个进程的线程使用。 |
2、pthread_spin_destroy
(1)声明
int pthread_spin_destroy(pthread_spinlock_t *lock);
(2)作用
销毁自旋锁。
(3)参数
参数名 | 描述 |
lock | 需要销毁的自旋锁变量。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
当一个线程持有自旋锁时,调用pthread_spin_destroy(),结果是未定义的。
当自旋锁未初始化,调用pthread_spin_destroy(),结果是未定义的。
(6)宏
无。
3、pthread_spin_lock
(1)声明
int pthread_spin_lock(pthread_spinlock_t *lock);
(2)作用
加自旋锁。
(3)参数
参数名 | 描述 |
lock | 需要上锁的自旋锁变量。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
当一个线程已经持有自旋锁,继续调用pthread_spin_lock(),结果是未定义的。
调用pthread_spin_lock()加锁一个未初始化的自旋锁,结果是未定义的。
(6)宏
无。
4、pthread_spin_trylock
(1)声明
int pthread_spin_trylock(pthread_spinlock_t *lock);
(2)作用
尝试加自旋锁,如果不可以立马获得锁,会返回宏EBUSY。
(3)参数
参数名 | 描述 |
lock | 需要上锁的自旋锁变量。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
调用pthread_spin_trylock()加锁一个未初始化的自旋锁,结果是未定义的。
(6)宏
无。
5、pthread_spin_unlock
(1)声明
int pthread_spin_unlock(pthread_spinlock_t *lock);
(2)作用
解锁自旋锁。
(3)参数
参数名 | 描述 |
lock | 需要解锁的自旋锁变量。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
当前线程未持有自旋锁,继续调用pthread_spin_unlock(),结果是未定义的。
调用pthread_spin_unlock()解锁一个未初始化的自旋锁,结果是未定义的。
(6)宏
无。
6、pthread_barrier_init
(1)声明
int pthread_barrier_init(pthread_barrier_t *__restrict__ __barrier, const pthread_barrierattr_t *__restrict__ __attr, unsigned int __count);
(2)作用
初始化线程屏障。
(3)参数
参数名 | 描述 |
__barrier | 需要初始化的屏障变量。 |
__attr | 屏障属性。 |
__count | 在所有线程继续运行之前,到达屏障的线程数。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
如果在未初始化的情况下使用屏障,则结果是未定义的。
如果调用 pthread_barrier_init() 指定已初始化的屏障,则结果是未定义的。
(6)宏
无。
7、pthread_barrier_destroy
(1)声明
int pthread_barrier_destroy(pthread_barrier_t *__barrier);
(2)作用
销毁线程屏障。
(3)参数
参数名 | 描述 |
__barrier | 需要销毁的屏障变量。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
如果pthread_barrier_destroy调用一个未初始化的屏障,结果是未定义的。
当任意线程在屏障上被锁住,此时调用pthread_barrier_destroy,结果是未定义的。
(6)宏
无。
8、pthread_barrierattr_init
(1)声明
int pthread_barrierattr_init(pthread_barrierattr_t *__attr);
(2)作用
初始化线程屏障属性。
(3)参数
参数名 | 描述 |
__attr | 屏障属性。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
如果pthread_barrierattr_init调用一个未初始化的屏障属性,结果是未定义的。
(6)宏
无。
9、pthread_barrierattr_destroy
(1)声明
int pthread_barrierattr_destroy(pthread_barrierattr_t *__attr);
(2)作用
销毁线程屏障属性。
(3)参数
参数名 | 描述 |
__attr | 屏障属性。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
无。
(6)宏
无。
9、pthread_barrierattr_getpshared
(1)声明
int pthread_barrierattr_getpshared(const pthread_barrierattr_t *__restrict__ __attr, int *__restrict__ __pshared);
(2)作用
获取屏障变量进程共享属性值。
(3)参数
参数名 | 描述 |
__attr | 屏障属性。 |
__pshared | 获取到的屏障变量进程共享属性值。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
无。
(6)宏
宏 | 描述 |
PTHREAD_PROCESS_PRIVATE | 只有同一个进程中的线程使用,默认值。 |
PTHREAD_PROCESS_SHARED | 可以多个进程的线程使用。 |
10、pthread_barrierattr_setpshared
(1)声明
int pthread_barrierattr_setpshared(pthread_barrierattr_t *__attr, int __pshared);
(2)作用
设置屏障变量进程共享属性值。
(3)参数
参数名 | 描述 |
__attr | 屏障属性。 |
__pshared | 设置的屏障变量进程共享属性值。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
无。
(6)宏
宏 | 描述 |
PTHREAD_PROCESS_PRIVATE | 只有同一个进程中的线程使用,默认值。 |
PTHREAD_PROCESS_SHARED | 可以多个进程的线程使用。 |
11、pthread_barrier_wait
(1)声明
int pthread_barrier_wait(pthread_barrier_t *__barrier);
(2)作用
屏障等待其他线程达到。
(3)参数
参数名 | 描述 |
__barrier | 需要设置的屏障锁属性变量。 |
(4)返回值
名称 | 描述 |
成功 | 返回0。 |
失败 | 返回错误码。 |
(5)注意点
无。
(6)宏
宏 | 描述 |
PTHREAD_BARRIER_SERIAL_THREAD | 任意一个线程返回PTHREAD_BARRIER_SERIAL_THREAD后,其他线程返回0,可以做为主线程来看,之后可以做其他事情。 |
四、锁测试验证
10个线程对全局变量进行累加,和为600000,表示测试正常。
我这边只是对于线程、线程属性、互斥锁、互斥锁属性做了简单封装,方便使用,如果大家感兴趣的话,可以在博客下面留言,我后面找一章分享出来。
1、互斥锁测试Demo
#include "MyThread.h"
#define THRD_ARRAY_LEN 10
#define SUM_VAL (600000 / 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_LOCK_F(Mutex) == SUCCESS_FLAG)
{
GlobalCnt++;
THRD_MUTEX_UNLOCK_F(Mutex);
}
}
THRD_EXIT(SUCCESS_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_NORMAL,
PTHREAD_MUTEX_ROBUST,
0,
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(Info,"GlobalCnt : %d.\n",GlobalCnt);
return SUCCESS_FLAG;
}
2、自旋锁测试Demo
#include "MyThread.h"
#define THRD_ARRAY_LEN 10
#define SUM_VAL (600000 / THRD_ARRAY_LEN)
int GlobalCnt = 0;
pthread_spinlock_t SpinLock;
void* TestFunc(void* Arg)
{
int i;
for ( i = 0; i < SUM_VAL; i++)
{
if (ThrdSpinLock(&SpinLock) == SUCCESS_FLAG)
{
GlobalCnt++;
ThrdSpinUnLock(&SpinLock);
}
}
THRD_EXIT(SUCCESS_FLAG);
}
Status main()
{
OneThrdSt **ThrdArray = (OneThrdSt **)MyMalloc(sizeof(OneThrdSt *) * THRD_ARRAY_LEN);
int i;
void *ThrdExitState = NULL;
ThrdSpinInit(&SpinLock, PTHREAD_PROCESS_PRIVATE);
for ( i = 0; i < THRD_ARRAY_LEN; i++)
{
OneThrdCreate(&(ThrdArray[i]),
PTHREAD_CREATE_JOINABLE,
PTHREAD_STACK_MIN,
ONE_PAGE_MEM_SIZE,
TestFunc,
NULL);
}
for ( i = 0; i < THRD_ARRAY_LEN; i++)
{
ThrdWait(ThrdArray[i]->ThreadId, &ThrdExitState);
LogFormat(Debug,"ThrdExitState : %ld.\n",(long)ThrdExitState);
OneThrdFree(&(ThrdArray[i]));
}
ThrdSpinDstry(&SpinLock);
free(ThrdArray);
ThrdArray = NULL;
LogFormat(Info,"GlobalCnt : %d.\n",GlobalCnt);
return SUCCESS_FLAG;
}
3、编译
[gbase@czg2 Pthread]$ make
gcc -Wall -Wextra -O3 -std=gnu11 TestSpin.c -o TestSpin -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/Log/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/Pthread/ -L /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/Make/Libs/ -L /usr/lib64/ -l PublicFunction -l Log -l MyThread
TestSpin.c: 在函数‘TestFunc’中:
TestSpin.c:9:22: 警告:未使用的参数‘Arg’ [-Wunused-parameter]
void* TestFunc(void* Arg)
^
gcc -Wall -Wextra -O3 -std=gnu11 TestMutex.c -o TestMutex -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/Log/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/Pthread/ -L /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/Make/Libs/ -L /usr/lib64/ -l PublicFunction -l Log -l MyThread
4、互斥锁测试
测试三组,都在68毫秒左右。
[gbase@czg2 Pthread]$ perf stat -e page-faults ./TestMutex
2024-03-25 09:42:49-P[4622]-T[140504432363328]-[Info ]-GlobalCnt : 600000.
Performance counter stats for './TestMutex':
249 page-faults:u
0.068061253 seconds time elapsed
0.060074000 seconds user
0.074329000 seconds sys
[gbase@czg2 Pthread]$ perf stat -e page-faults ./TestMutex
2024-03-25 09:42:51-P[4642]-T[140690703296320]-[Info ]-GlobalCnt : 600000.
Performance counter stats for './TestMutex':
249 page-faults:u
0.064127278 seconds time elapsed
0.047671000 seconds user
0.076923000 seconds sys
[gbase@czg2 Pthread]$ perf stat -e page-faults ./TestMutex
2024-03-25 09:42:52-P[4661]-T[139921704650560]-[Info ]-GlobalCnt : 600000.
Performance counter stats for './TestMutex':
249 page-faults:u
0.068365957 seconds time elapsed
0.065637000 seconds user
0.067688000 seconds sys
5、自旋锁测试
测试三组,都在十几到二十毫秒左右。
[gbase@czg2 Pthread]$ perf stat -e page-faults ./TestSpin
2024-03-25 09:44:09-P[4721]-T[139990554580800]-[Info ]-GlobalCnt : 600000.
Performance counter stats for './TestSpin':
248 page-faults:u
0.017746978 seconds time elapsed
0.027653000 seconds user
0.004424000 seconds sys
[gbase@czg2 Pthread]$ perf stat -e page-faults ./TestSpin
2024-03-25 09:44:11-P[4748]-T[139808353724224]-[Info ]-GlobalCnt : 600000.
Performance counter stats for './TestSpin':
248 page-faults:u
0.026674296 seconds time elapsed
0.048756000 seconds user
0.002321000 seconds sys
[gbase@czg2 Pthread]$ perf stat -e page-faults ./TestSpin
2024-03-25 09:44:12-P[4767]-T[140348668368704]-[Info ]-GlobalCnt : 600000.
Performance counter stats for './TestSpin':
248 page-faults:u
0.022916708 seconds time elapsed
0.041160000 seconds user
0.003087000 seconds sys
6、总结
上面的验证结果为自旋锁效果远高于互斥锁,但这只能说明在操作临界资源时间短的情况下是自旋锁效率高,也就是自旋锁短暂空耗CPU的消耗小于互斥锁进程状态切换的消耗。大家可以自己写一个另一种情况下的Demo,实验一下是不是这么回事。
五、屏障测试验证
实现内容为:每个线程累加,都到达屏障后,进行加和。
1、Demo
#include "MyThread.h"
#define THRD_ARRAY_LEN 3
#define SUM_VAL (900 / THRD_ARRAY_LEN)
typedef struct TestSt
{
int GlobalArray[THRD_ARRAY_LEN];
int ThrdIdx;
OneThrdBarrierSt *Barrier;
pthread_spinlock_t SpinLock;
}TestSt;
void* TestFunc(void* Arg)
{
TestSt* St = (TestSt*)Arg;
if (ThrdSpinLock(&(St->SpinLock)) == FAIL_FLAG)
{
THRD_EXIT(FAIL_FLAG);
}
int Index = St->ThrdIdx;
(St->ThrdIdx)++;
ThrdSpinUnLock(&(St->SpinLock));
int i;
for ( i = 0; i < SUM_VAL; i++)
{
St->GlobalArray[Index]++;
}
THRD_BARRIER_WAIT_F(St->Barrier);
THRD_EXIT(SUCCESS_FLAG);
}
Status main()
{
OneThrdSt **ThrdArray = (OneThrdSt **)MyMalloc(sizeof(OneThrdSt *) * THRD_ARRAY_LEN);
int i;
void *ThrdExitState = NULL;
TestSt St;
int SumVal = 0;
St.ThrdIdx = 0;
ThrdSpinInit(&(St.SpinLock), PTHREAD_PROCESS_PRIVATE);
OneThrdBarrierCreate(&(St.Barrier), PTHREAD_PROCESS_PRIVATE, THRD_ARRAY_LEN + 1);
for ( i = 0; i < THRD_ARRAY_LEN; i++)
{
St.GlobalArray[i] = 0;
OneThrdCreate(&(ThrdArray[i]),
PTHREAD_CREATE_JOINABLE,
PTHREAD_STACK_MIN,
ONE_PAGE_MEM_SIZE,
TestFunc,
&St);
}
THRD_BARRIER_WAIT_F(St.Barrier);
for ( i = 0; i < THRD_ARRAY_LEN; i++)
{
SumVal += St.GlobalArray[i];
}
for ( i = 0; i < THRD_ARRAY_LEN; i++)
{
ThrdWait(ThrdArray[i]->ThreadId, &ThrdExitState);
LogFormat(Debug,"ThrdExitState : %ld.\n",(long)ThrdExitState);
OneThrdFree(&(ThrdArray[i]));
}
ThrdSpinDstry(&(St.SpinLock));
OneThrdBarrierFree(&(St.Barrier));
free(ThrdArray);
ThrdArray = NULL;
LogFormat(Info,"SumVal : %d.\n",SumVal);
return SUCCESS_FLAG;
}
2、编译
gcc -Wall -Wextra -O3 -std=gnu11 TestBarrier.c -o TestBarrier -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/Log/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/Pthread/ -L /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/Make/Libs/ -L /usr/lib64/ -l PublicFunction -l Log -l MyThread
gcc -Wall -Wextra -O3 -std=gnu11 TestSpin.c -o TestSpin -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/Log/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/Pthread/ -L /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/Make/Libs/ -L /usr/lib64/ -l PublicFunction -l Log -l MyThread
TestSpin.c: 在函数‘TestFunc’中:
TestSpin.c:9:22: 警告:未使用的参数‘Arg’ [-Wunused-parameter]
void* TestFunc(void* Arg)
^
gcc -Wall -Wextra -O3 -std=gnu11 TestMutex.c -o TestMutex -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/Log/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/Pthread/ -L /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/Make/Libs/ -L /usr/lib64/ -l PublicFunction -l Log -l MyThread
3、测试
[gbase@czg2 Pthread]$ perf stat -e page-faults ./TestBarrier
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-ThrdSpinInit : OK, SharedVal : PTHREAD_PROCESS_PRIVATE.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-BarrierAttrInit : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-BarrierAttrSetShrd : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-ThrdBarrierInit : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-BarrierAttrGetShrd : OK, SharedVal : PTHREAD_PROCESS_PRIVATE.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-BarrierAttrDstry : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-BarrierCreate : OK, Cnt : 4.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-ThrdAttrInit : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-SetDetachState : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-SetStackSize : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-SetGuardSize : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-ThrdCreate : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-GetDetachState : OK, DetachState : PTHREAD_CREATE_JOINABLE.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-GetStackSize : OK, StackSize : 16384.
2024-03-25 16:03:05-P[12071]-T[140175572850432]-[Debug]-ThrdSpinLock : OK.
2024-03-25 16:03:05-P[12071]-T[140175572850432]-[Debug]-ThrdSpinUnLock : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-GetGuardSize : OK, GuardSize : 4096.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-ThrdAttrDestroy : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-OneThrdCreate : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-ThrdAttrInit : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-SetDetachState : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-SetStackSize : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-SetGuardSize : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-ThrdCreate : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-GetDetachState : OK, DetachState : PTHREAD_CREATE_JOINABLE.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-GetStackSize : OK, StackSize : 16384.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-GetGuardSize : OK, GuardSize : 4096.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-ThrdAttrDestroy : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-OneThrdCreate : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-ThrdAttrInit : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-SetDetachState : OK.
2024-03-25 16:03:05-P[12071]-T[140175572829952]-[Debug]-ThrdSpinLock : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-SetStackSize : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-SetGuardSize : OK.
2024-03-25 16:03:05-P[12071]-T[140175572829952]-[Debug]-ThrdSpinUnLock : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-ThrdCreate : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-GetDetachState : OK, DetachState : PTHREAD_CREATE_JOINABLE.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-GetStackSize : OK, StackSize : 16384.
2024-03-25 16:03:05-P[12071]-T[140175572809472]-[Debug]-ThrdSpinLock : OK.
2024-03-25 16:03:05-P[12071]-T[140175572809472]-[Debug]-ThrdSpinUnLock : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-GetGuardSize : OK, GuardSize : 4096.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-ThrdAttrDestroy : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-OneThrdCreate : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-ThrdBarrierWait : OK, All threads arrive at the barrier.
2024-03-25 16:03:05-P[12071]-T[140175572829952]-[Debug]-ThrdBarrierWait : OK.
2024-03-25 16:03:05-P[12071]-T[140175572850432]-[Debug]-ThrdBarrierWait : OK.
2024-03-25 16:03:05-P[12071]-T[140175572809472]-[Debug]-ThrdBarrierWait : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-ThrdWait : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-ThrdExitState : 0.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-OneThrdFree : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-ThrdWait : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-ThrdExitState : 0.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-OneThrdFree : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-ThrdWait : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-ThrdExitState : 0.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-OneThrdFree : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-ThrdSpinDstry : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-ThrdBarrierDstry : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Debug]-OneThrdBarrierFree : OK.
2024-03-25 16:03:05-P[12071]-T[140175572858688]-[Info ]-SumVal : 900.
Performance counter stats for './TestBarrier':
240 page-faults:u
0.003126995 seconds time elapsed
0.001257000 seconds user
0.001257000 seconds sys