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

news2024/9/20 1:05:15

目录

一、多线程相关文章链接

二、自由抒发

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.coloradmin.cn/o/1546753.html

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

相关文章

c语言文件操作(下)

目录 1.文件的随机读写1.1 fseek1.2 ftell1.3 rewind 2. 文件结束的判定2.1 文本文件读取结束的判断2.2 二进制文件读取结束的判断 3. 文件缓冲区 1.文件的随机读写 1.1 fseek 根据⽂件指针的位置和偏移量来定位⽂件指针。 函数原型&#xff1a; int fseek (FILE * stream,…

Python篇之网络编程,实现简单的服务端和客户端的内容传输

本小节内容&#xff1a;实现简单的信息交流 文章目录 一、 Socket介绍二、客户端与服务端三、在python中实现网络通信1. 服务端2. 客户端3. 连接测试 一、 Socket介绍 socket (简称 套接字) 模块是其内置的标准库之一&#xff0c;它实现了BSD sockets API&#xff0c;允许开发…

(分享)一个图片添加水印的小demo的页面,可自定义样式

有时候想给某张图片添加一个自己的水印&#xff0c;但是又懒的下载相应软件&#xff0c;用js canvas制作一个静态页面&#xff0c;对于单张图片添加自定义文字水印&#xff0c;大小 间距&#xff0c;角度可调。 页面如下&#xff1a; 选择图片&#xff0c;设置相应参数&#x…

深度学习模型部署(十二)CUDA编程-绪

CUDA 运行时 API 与 CUDA 驱动 API 速度没有差别&#xff0c;实际中使用运行时 API 较多&#xff0c;运行时 API 是在驱动 API 上的一层封装。​ CUDA 是什么&#xff1f;​ CUDA(Compute Unified Device Architecture) 是 nvidia 推出的一个通用并行技术架构&#xff0c;用它…

【LLM】大模型推理加速 KV-Cache

目录 模型推理过程KV Cache原理KV Cache的存储 模型推理过程 在了解KVCache之前&#xff0c;我们需要知道Transformer类大模型的推理过程。 对于LLM进行一次前向传播也就是生成一个token的过程可以被分解成以下步骤&#xff1a; 文本 T i n p u t T_{input} Tinput​经过Toke…

数据结构与算法分析引论1

1.解决问题的算法有很多&#xff0c;但是在输入不同的情况下&#xff0c;不同算法之间的差异也很大&#xff0c;我们总是追求一个更快、更有效的方法。比如说普通的依次查找和二分查找&#xff0c;两者的差异就很大。我们使用大O表示法来表示算法的速度。依次查找就是O(n)&…

MATLAB 自定义生成平面点云(可指定方向,添加噪声)(48)

MATLAB 自定义生成平面点云(可指定方向,添加噪声)(48) 一、算法介绍二、算法步骤三、算法实现1.代码2.效果一、算法介绍 通过这里的平面生成方法,可以生成模拟平面的点云数据,并可以人为设置平面方向,平面大小,并添加噪声来探索不同类型的平面数据。这种方法可以用于…

UDS诊断中的NRC

我总结了一张表格&#xff1a;详细解释了NRC的分布情况和NRC的触发条件 1&#xff1a;基本概念 NRC 全称Negative Response Code(否定响应代码)&#xff0c;是指示uds诊断中的&#xff0c;指示否定响应的原因 例如&#xff1a;0x22 服务 request 报文 0x618 03 22 F1 34 0…

电脑物理磁盘空间不足?试试这5种清理和优化方法!

随着我们使用电脑的时间越来越长&#xff0c;物理磁盘空间可能会逐渐变得捉襟见肘。当你的电脑提示磁盘空间不足时&#xff0c;不要慌张&#xff0c;这里有五种方法可以帮助你清理和优化电脑&#xff0c;释放宝贵的存储空间。 1. 卸载不常用的程序和游戏 许多用户在安装软件和…

机器学习基础——模型评估与选择(部分)

目录 一、前言&#xff1a;误差与拟合 &#xff08;一&#xff09;经验误差 &#xff08;二&#xff09;过拟合、欠拟合 二、评估方法 &#xff08;一&#xff09;评估总体的思路 &#xff08;二&#xff09;如何划分训练集和测试集 1.留出法 2.k折交叉验证 3.自助法 …

程序员35岁真的就是危机吗?

前言 35岁被认为是程序员职业生涯的分水岭&#xff0c;许多程序员开始担忧自己的职业发展是否会受到年龄的限制。有人担心随着年龄的增长&#xff0c;技术更新换代的速度会使得资深程序员难以跟上&#xff1b;而另一些人则认为&#xff0c;丰富的经验和深厚的技术积累是年轻程…

knife4j/swagger救援第一现场

1、前方来报&#xff0c;测试环境springboot项目无法启动&#xff0c;现场如下&#xff1a; Error starting ApplicationContext. To display the auto-configuration report re-run your application with debug enabled. [ERROR] 2024-03-20 12:54:42,718 --main-- [org.spr…

一键跳过开屏广告,这下舒服了

现在的app开屏广告越来越过分了&#xff0c;不小心摇一摇翻转就点开广告了。 今天分享个强大的自动跳过广告https://github.com/gkd-kit/gkd&#xff0c;李跳跳替代品&#xff0c;下载地址在公众号后台对话框回复 广告 玩转互联网达人 苏生不惑备用号&#xff0c;分享各种黑科…

【Godot4自学手册】第二十九节使用Shader来实现敌人受伤的闪白效果

在Godot 4中&#xff0c;Shader是用来为材质提供自定义渲染效果的程序。材质可以应用于MeshInstance、CanvasItem和ParticleEmitter等节点。Shader可以影响顶点的变换、片段&#xff08;像素&#xff09;的颜色&#xff0c;以及光照与物体的交互。 在Godot中&#xff0c;Shader…

HTML基础:8个常见表单元素的详解

你好&#xff0c;我是云桃桃。 一个希望帮助更多朋友快速入门 WEB 前端程序媛。 后台回复“前端工具”可免费获取开发工具&#xff0c;持续更新。 今天来说说 HTML 表单。它是用于收集用户输入信息的元素集合。例如文本框、单选按钮、复选框、下拉列表等。 用户经常填写的表…

海外媒体软文发稿:谷歌关键词优化细分人群成功案例,突破海外市场!

海外媒体软文发稿&#xff1a;谷歌关键词优化细分人群成功案例&#xff0c;突破海外市场&#xff01; 引言 在全球化的时代&#xff0c;海外市场对于企业的发展至关重要。而在海外市场中&#xff0c;互联网媒体的作用不可忽视。本篇教程将介绍如何通过谷歌关键词优化细分人群…

西井科技与安通控股签署战略合作协议 共创大物流全新生态

2024年3月21日&#xff0c;西井科技与安通控股在“上海硅巷”新象限空间正式签署战略合作框架协议。双方基于此前在集装箱物流的成功实践与资源优势&#xff0c;积极拓展在AI数字化产品、新能源自动驾驶解决方案和多场景应用&#xff0c;以及绿色物流链等领域的深度探索、强强联…

2024.3.23

1、使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0c;密码是否…

鸿蒙应用开发-录音并使用WebSocket实现实时语音识别

功能介绍&#xff1a; 录音并实时获取RAW的音频格式数据&#xff0c;利用WebSocket上传数据到服务器&#xff0c;并实时获取语音识别结果&#xff0c;参考文档使用AudioCapturer开发音频录制功能(ArkTS)&#xff0c;更详细接口信息请查看接口文档&#xff1a;AudioCapturer8和…

如何推进制造业数字化转型?《制造业数字化转型白皮书》分享给你

分享一份《制造业数字化转型白皮书》给你&#xff0c;希望对你有所帮助&#xff01; 内容较长&#xff0c;防止后续找不到&#xff0c;建议先收藏&#xff01; 变局&#xff1a;数字经济浪潮“不期而至” 中国制造何去何从&#xff1f; VUCA&#xff08;不稳定 Volatile、不确…