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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

docker centos7安装jdk1.8(在线和离线方式)

目录 1.在线方式1.1.进入容器1.2.使用yum安装openjdk1.3.配置环境变量 2.离线方式2.1.下载jdk安装包2.2.解压2.3.配置环境变量 3.可能遇到的问题 1.在线方式 1.1.进入容器 1.2.使用yum安装openjdk # 安装JDK1.8 yum install java-1.8.0-openjdkjava -version1.3.配置环境变量…

RPA-财务对账邮件应用自动化(客户对账机器人)

《财务对账邮件应用自动化》&#xff0c;将会使用邮箱的SMTP服务&#xff0c;小北把资源包绑定在这篇博客了 Uibot (RPA设计软件)———机器人的小项目友友们可以参考小北的课前材料五博客~ (本博客中会有部分课程ppt截屏,如有侵权请及请及时与小北我取得联系~&#xff09; …

Netty学习——源码篇6 Pipeline设计原理 备份

1 Pipeline设计原理 在Netty中每个Channel都有且仅有一个ChannelPipeline与之对应&#xff0c;它们的组成关系如下图&#xff1a; 通过上图可以看到&#xff0c;一个Channel包含了一个ChannelPipeline&#xff0c;而ChannelPipeline中又维护了一个由ChannelHandlerContext组成的…

零基础学python之高级编程(6)---Python中进程的Queue 和进程锁,以及进程池的创建 (包含详细注释代码)

Python中进程的Queue 和进程锁,以及进程池的创建 文章目录 Python中进程的Queue 和进程锁,以及进程池的创建前言一、进程间同步通信(Queue)二、进程锁&#xff08;Lock&#xff09;三、创建进程池Poorpool 类方法: End! 前言 大家好,上一篇文章,我们初步接触了进程的概念及其应…

【随笔】Git -- 常用命令(四)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

第16篇:奇偶校验器

Q&#xff1a;本期我们将实现4位奇偶校验逻辑电路&#xff0c;即校验4位二进制代码中 “1” 的个数是奇数或偶数。 A&#xff1a;奇偶校验器的基本原理&#xff1a;采用异或运算对“1”的奇偶个数进行校验&#xff0c;从最高位依次往最低位进行连续异或运算。如果最后的异或运…

stm32控制电机--计算电角度以及电角度和机械角度的对应关系---以及foc的控制算法模型及过程(推荐)

1&#xff0c;电角度和机械角度的关系 如何区分电角度和机械角度&#xff1f; 2&#xff0c;foc模型工程&#xff08;推荐&#xff09; SimpleFOC移植STM32&#xff08;四&#xff09;—— 闭环控制 注意速度需要进行低通滤波

使用Docker Compose一键部署前后端分离项目(图文保姆级教程)

一、安装Docker和docker Compose 1.Docker安装 //下载containerd.io包 yum install https://download.docker.com/linux/fedora/30/x86_64/stable/Packages/containerd.io-1.2.6-3.3.fc30.x86_64.rpm //安装依赖项 yum install -y yum-utils device-mapper-persistent-data l…

消费电子回暖之际,手机回收厂商如何持续释放“绿色潜力”?

春天到来的暖意&#xff0c;正在消费电子产业链上下游蔓延。 仅就手机这一品类而言&#xff0c;可以看到&#xff0c;2023年手机厂商已经度过寒冬&#xff0c;中国信息通信研究院发布的数据显示&#xff0c;2023年1-12月&#xff0c;我国手机总体出货量累计2.89亿部&#xff0…

新生儿奶瓶怎么选择?5款口碑榜单奶瓶推荐

新生儿奶瓶是每个新手爸妈都要选择的喂养产品&#xff0c;除了喂养宝宝外&#xff0c;还能帮助宝宝渡过戒奶期。然而近年来&#xff0c;市面上出现一些低质量、劣质材料制成的奶瓶&#xff0c;频频被爆安全隐患&#xff0c;给消费者带来极大的不便和风险。那么你知道什么牌子的…

Linux的学习之路:1、发展史与编译环境的搭建

一、发展史 1991年10月5日&#xff0c;赫尔辛基大学的一名研究生Linus Benedict Torvalds在一个Usenet新闻组 &#xff08;comp.os.minix&#xff09;中宣布他编制出了一种类似UNIX的小操作系统&#xff0c;叫Linux。新的操作系统是受到另一个UNIX的小操作系统——Minix的启发…

Cisco firepower 2140 run ASA and config failover

1 背景 here we got 2 cisco firepower 2140 hardware appliance we’re planning to run ASA on it. and config failover for Primary Unit and Secondary Unit 现场2台Cisco firepower 2140防火墙&#xff0c; 运行ASA模式&#xff0c; 双机组HA&#xff0c;心跳线使用E1/1…

服务器基础知识(物理服务器云服务器)

今天我们来介绍一下服务器的基础知识 一、服务器硬件基础知识 组件说明中央处理器&#xff08;CPU&#xff09;CPU是服务器的大脑&#xff0c;负责执行计算任务和指令。服务器通常配备多个CPU核心&#xff0c;以支持并行处理和提高性能。关键的CPU性能指标包括时钟频率、核心数…

sonarqube使用指北(三)-编写代码进行自动化扫描

一、引言 上一篇文章之后 我们应该已经成功完成的配置了扫描环境并执行了一次基本的本地扫描,但是之前的手动扫描需要我们每一次都手动切换到代码目标并手动执行扫描命令,效率很低。在代码库较大的情况下会占用大量的时间。这一章我们会通过编写python代码的形式来实现自动化…

Python学习:循环语句

Python循环语句 概念 循环语句是编程中常用的结构&#xff0c;用于多次执行相同或类似的代码块。Python中有两种主要的循环语句&#xff1a;for循环和while循环。 for循环&#xff1a; for循环用于遍历一个序列&#xff08;如列表、元组、字符串等&#xff09;中的元素&#x…

二十二、软考-系统架构设计师笔记-真题解析-2018年真题

软考-系统架构设计师-2018年上午选择题真题 考试时间 8:30 ~ 11:00 150分钟 1.在磁盘调度管理中&#xff0c;应先进行移臂调度&#xff0c;再进行旋转调度。假设磁盘移动臂位于21号柱面上&#xff0c;进程的请求序列如下表所示。如果采用最短移臂调度算法&#xff0c;那么系统…

PyPy为什么能让Python比C还快?一文了解内在机制

「如果想让代码运行得更快&#xff0c;您应该使用 PyPy。」—— Python 之父 Guido van Rossum 对于研究人员来说&#xff0c;迅速把想法代码化并查看其是否行得通至关重要。Python 是能够实现这一目标的出色语言&#xff0c;它能够让人们专注于想法本身&#xff0c;而不必过度…

万亿功能性食品市场爆火,北美膳食健康品牌GNITE如何抓住“朋克养生”年轻人!

近几年&#xff0c;年轻人的养生意识不断提升&#xff0c;“吃出健康”理念盛行&#xff0c;在中国年轻人独有的“懒养生”理念加持下&#xff0c;功能性软糖精准击中年轻人的健康焦虑&#xff0c;助眠、美白、护眼、补铁、减脂……等产品在新消费领域兴起&#xff0c;消费热度…

邮件接口与第三方平台的集成的方式有哪些?

邮件接口如何实现高效通信&#xff1f;怎么有效地利用邮件接口&#xff1f; 邮件接口与第三方平台的集成已经成为了企业提升工作效率、优化用户体验的关键环节。那么&#xff0c;邮件接口与第三方平台的集成方式究竟有哪些呢&#xff1f;接下来&#xff0c;AokSend就来探讨一下…
最新文章