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)声明

cpp 复制代码
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)声明

cpp 复制代码
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)声明

cpp 复制代码
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)声明

cpp 复制代码
int pthread_spin_trylock(pthread_spinlock_t *lock);

(2)作用

尝试加自旋锁,如果不可以立马获得锁,会返回宏EBUSY。

(3)参数

|------|-------------|
| 参数名 | 描述 |
| lock | 需要上锁的自旋锁变量。 |

(4)返回值

|----|--------|
| 名称 | 描述 |
| 成功 | 返回0。 |
| 失败 | 返回错误码。 |

(5)注意点

调用pthread_spin_trylock()加锁一个未初始化的自旋锁,结果是未定义的。

(6)宏

无。

5、pthread_spin_unlock

(1)声明

cpp 复制代码
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)声明

cpp 复制代码
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)声明

cpp 复制代码
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)声明

cpp 复制代码
int pthread_barrierattr_init(pthread_barrierattr_t *__attr);

(2)作用

初始化线程屏障属性。

(3)参数

|--------|-------|
| 参数名 | 描述 |
| __attr | 屏障属性。 |

(4)返回值

|----|--------|
| 名称 | 描述 |
| 成功 | 返回0。 |
| 失败 | 返回错误码。 |

(5)注意点

如果pthread_barrierattr_init调用一个未初始化的屏障属性,结果是未定义的。

(6)宏

无。

9、pthread_barrierattr_destroy

(1)声明

cpp 复制代码
int pthread_barrierattr_destroy(pthread_barrierattr_t *__attr);

(2)作用

销毁线程屏障属性。

(3)参数

|--------|-------|
| 参数名 | 描述 |
| __attr | 屏障属性。 |

(4)返回值

|----|--------|
| 名称 | 描述 |
| 成功 | 返回0。 |
| 失败 | 返回错误码。 |

(5)注意点

无。

(6)宏

无。

9、pthread_barrierattr_getpshared

(1)声明

cpp 复制代码
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)声明

cpp 复制代码
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)声明

cpp 复制代码
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

cpp 复制代码
#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

cpp 复制代码
#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、编译

bash 复制代码
[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毫秒左右。

bash 复制代码
[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、自旋锁测试

测试三组,都在十几到二十毫秒左右。

bash 复制代码
[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

cpp 复制代码
#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、编译

bash 复制代码
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、测试

bash 复制代码
[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
相关推荐
若亦_Royi7 分钟前
C++ 的大括号的用法合集
开发语言·c++
资源补给站1 小时前
大恒相机开发(2)—Python软触发调用采集图像
开发语言·python·数码相机
m0_748247551 小时前
Web 应用项目开发全流程解析与实战经验分享
开发语言·前端·php
eybk2 小时前
Pytorch+Mumu模拟器+萤石摄像头实现对小孩学习的监控
学习
6.942 小时前
Scala学习记录 递归调用 练习
开发语言·学习·scala
FF在路上2 小时前
Knife4j调试实体类传参扁平化模式修改:default-flat-param-object: true
java·开发语言
余额不足121383 小时前
C语言基础十六:枚举、c语言中文件的读写操作
linux·c语言·算法
众拾达人3 小时前
Android自动化测试实战 Java篇 主流工具 框架 脚本
android·java·开发语言
皓木.3 小时前
Mybatis-Plus
java·开发语言
不良人天码星3 小时前
lombok插件不生效
java·开发语言·intellij-idea