Unix环境高级编程-学习-08-自旋锁与屏障

目录

一、多线程相关文章链接

二、自由抒发

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)宏

   9、pthread_barrierattr_getpshared

(1)声明

(2)作用

(3)参数

(4)返回值

(5)注意点

(6)宏

    10、pthread_barrierattr_setpshared

(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 elapsed0.060074000 seconds user0.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 elapsed0.047671000 seconds user0.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 elapsed0.065637000 seconds user0.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 elapsed0.027653000 seconds user0.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 elapsed0.048756000 seconds user0.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 elapsed0.041160000 seconds user0.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 elapsed0.001257000 seconds user0.001257000 seconds sys

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/770696.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

libVLC 视频裁剪

使用 libVLC 进行视频裁剪并不是直接支持的功能&#xff0c;因为 libVLC 主要是一个媒体播放库。然而&#xff0c;你可以通过调整播放窗口的大小和设置视频输出的区域来实现一种“视觉上的裁剪”。这意味着视频本身并没有被修改&#xff0c;但可以控制显示给用户的视频区域。 …

[网鼎杯2018]Unfinish 两种方法 -----不会编程的崽

网鼎杯太喜欢搞二次注入了吧。上次是无列名盲注&#xff0c;这次又是二次注入盲注。。。不知道方法还是挺难的。哎&#xff0c;网鼎嘛&#xff0c;能理解透彻就很强了。能自己做出来那可太nb了。 又是熟悉的登录框。不知道这是第几次看见网鼎杯的登录框了。后台扫描一下&#x…

『Apisix入门篇』从零到一掌握Apache APISIX:架构解析与实战指南

&#x1f4e3;读完这篇文章里你能收获到&#xff1a; &#x1f310; 深入Apache APISIX架构&#xff1a; 从Nginx到OpenResty&#xff0c;再到etcd&#xff0c;一站式掌握云原生API网关的构建精髓&#xff0c;领略其层次化设计的魅力。 &#x1f50c; 核心组件全解析&#xff…

【嵌入式学习】Qtday03.26

一、思维导图 二、练习 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }void Widget::on_login_btn_clicked() {if(ui->…

OC对象 - Block解决循环引用

文章目录 OC对象 - Block解决循环引用前言1. 循环引用示例1.1 分析 2. 解决思路3. ARC下3.1 __weak3.2 __unsafe_unretained3.3 __block 4. MRC下4.1 __unsafe_unretain....4.1 __block 5. 总结5.1 ARC下5.2 MRC下 OC对象 - Block解决循环引用 前言 本章将会通过一个循环引用…

flask_restful的基本使用

优势&#xff1a; Flask-Restful 是一个专门用来写 restful api 的一个插件。 使用它可以快速的集成restful api 接口功能。 在系统的纯api 的后台中&#xff0c;这个插件可以帮助我们节省很多时间。 缺点&#xff1a; 如果在普通的网站中&#xff0c;这个插件就没有优势了&…

测试环境搭建整套大数据系统(十二:挂载磁盘到hadoop环境)

一&#xff1a;链接硬盘 将硬盘连接到计算机的 SATA 接口或 USB 接口&#xff0c;并确保硬盘通电并处于可用状态。 二&#xff1a;查看硬盘信息 sudo fdisk -l三&#xff1a;创建分区 gdisk /dev/vbd重新扫描磁盘 partprobe /dev/vdb格式化磁盘 mkfs.ext4 /dev/vdb2查看磁…

前端学习之css基本网格布局

网格布局 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>网格布局</title><style>.a{/* grid网格布局 */display: grid;width: 400px;height: 400px;border: 1px solid red;/* 设置当前…

iOS开发之SwiftUI

iOS开发之SwiftUI 在iOS开发中SwiftUI与Objective-C和Swift不同&#xff0c;它采用了声明式语法&#xff0c;相对而言SwiftUI声明式语法简化了界面开发过程&#xff0c;减少了代码量。 由于SwiftUI是Apple推出的界面开发框架&#xff0c;从iOS13开始引入&#xff0c;Apple使用…

我在京东做数据分析,一位京东数据分析师的工作日常

有人说&#xff1a;“种下一棵树最好的时间是十年前&#xff0c;其次是现在”。任何时候&#xff0c;我们都应该抓住机遇&#xff0c;说不定就是改变你现状的一个机会。 2020年&#xff0c;我在疫情得到控制后&#xff0c;面试入职京东大数据组&#xff0c;截止目前&#xff0…

获取高德安全码SHA1

高德开发者平台上给的三种方法 获取安全码SHA1&#xff0c;这里我自己使用的是第三种方法。 1、通过Eclipse编译器获取SHA1 使用 adt 22 以上版本&#xff0c;可以在 eclipse 中直接查看。 Windows&#xff1a;依次在 eclipse 中打开 Window -> Preferances -> Androi…

flask_restful结合蓝图使用

在蓝图中&#xff0c;如果使用 Flask_RESTful &#xff0c; 创建 Api 对象的时候&#xff0c;传入蓝图对象即可&#xff0c;不再是传入 app 对象 /user/__init__.py from flask.blueprints import Blueprintuser_bp Blueprint(user,__name__)from user import views /user…

word文件如何转PDF格式?word转PDF的方法

在当今数字化时代&#xff0c;文档格式的转换已成为日常生活和工作中不可或缺的一部分。其中&#xff0c;将Word文档转换为PDF格式更是受到了广大用户的青睐。本文将详细介绍Word转PDF的方法&#xff0c;帮助读者轻松实现文档格式的转换&#xff0c;并探讨转换过程中的注意事项…

工业互联网下的增强现实

工业互联网下的增强现实 1、 概述 增强现实&#xff08;Augmented Reality&#xff0c;简称AR&#xff09;&#xff0c;增强现实技术也被称为扩增现实&#xff0c;AR增强现实技术是促使真实世界信息和虚拟世界信息内容之间综合在一起的较新的技术内容&#xff0c;其将原本在现…

【浅尝C++】类和对象第二弹=>类的6个默认成员函数/运算符重载详谈

&#x1f3e0;专栏介绍&#xff1a;浅尝C专栏是用于记录C语法基础、STL及内存剖析等。 &#x1f6a9;一些备注&#xff1a;之前的文章有点杂乱&#xff0c;这里将前面的知识点重新组织了&#xff0c;避免了过多冗余的废话。 &#x1f3af;每日努力一点点&#xff0c;技术变化看…

Appium Inspector 展示设备当前页面

定位元素需要使用appium inspector&#xff0c;之前每次都是从登录页开始&#xff0c;后来发现连接设备的时候只需要去掉appPackage、appActivity即可。 { "platformName": "Android", "platformVersion": "6", "deviceNa…

35.网络游戏逆向分析与漏洞攻防-游戏网络通信数据解析-登录成功数据包内容分析

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果 内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;34.登录数据包的…

LGBM算法 原理

简介 GBDT (Gradient Boosting Decision Tree) 是机器学习中一个长盛不衰的模型&#xff0c;其主要思想是利用弱分类器&#xff08;决策树&#xff09;迭代训练以得到最优模型&#xff0c;该模型具有训练效果好、不易过拟合等优点。GBDT不仅在工业界应用广泛&#xff0c;通常被…

伪装目标检测之注意力CBAM:《Convolutional Block Attention Module》

论文地址&#xff1a;link 代码&#xff1a;link 摘要 我们提出了卷积块注意力模块&#xff08;CBAM&#xff09;&#xff0c;这是一种简单而有效的用于前馈卷积神经网络的注意力模块。给定一个中间特征图&#xff0c;我们的模块依次推断沿着两个独立维度的注意力图&#xff…

10.2024

使用选择排序将{2,9,5,0,1,3,6,8}排序 代码&#xff1a; public class 第十题 {public static void main(String[] args) {int a[]{2,9,5,0,1,3,6,8};int begin0;int enda.length-1;while (begin<end){int mina[begin];int tbegin;for (int ibegin;i<end;i){if(min>…