Unix环境高级编程-学习-07-多线程之互斥锁

目录

 

一、自由抒发

二、函数介绍

 1、pthread_mutex_init

(1)声明

(2)作用

(3)参数

(4)返回值

(5)注意点

(6)宏

 2、pthread_mutex_destroy

(1)声明

(2)作用

(3)参数

(4)返回值

(5)注意点

(6)宏

 3、pthread_mutexattr_init

(1)声明

(2)作用

(3)参数

(4)返回值

(5)注意点

(6)宏

 4、pthread_mutexattr_destroy

(1)声明

(2)作用

(3)参数

(4)返回值

(5)注意点

(6)宏

 5、pthread_mutexattr_getpshared

(1)声明

(2)作用

(3)参数

(4)返回值

(5)注意点

(6)宏

 6、pthread_mutexattr_setpshared

(1)声明

(2)作用

(3)参数

(4)返回值

(5)注意点

(6)宏

 7、pthread_mutexattr_gettype

(1)声明

(2)作用

(3)参数

(4)返回值

(5)注意点

(6)宏

 8、pthread_mutexattr_settype

(1)声明

(2)作用

(3)参数

(4)返回值

(5)注意点

(6)宏

  9、pthread_mutexattr_getrobust

(1)声明

(2)作用

(3)参数

(4)返回值

(5)注意点

(6)宏

  10、pthread_mutexattr_setrobust

(1)声明

(2)作用

(3)参数

(4)返回值

(5)注意点

(6)宏

  11、pthread_mutex_consistent

(1)声明

(2)作用

(3)参数

(4)返回值

(5)注意点

(6)宏

 12、pthread_mutex_lock

(1)声明

(2)作用

(3)参数

(4)返回值

(5)注意点

(6)宏

 13、pthread_mutex_unlock

(1)声明

(2)作用

(3)参数

(4)返回值

(5)注意点

(6)宏

  14、pthread_mutex_trylock

(1)声明

(2)作用

(3)参数

(4)返回值

(5)注意点

(6)宏

  15、pthread_mutex_timedlock

(1)声明

(2)作用

(3)参数

(4)返回值

(5)注意点

(6)宏

三、如何避免死锁

1、重复加锁

2、互持锁

四、测试与练习

1、部分demo源码

2、编译

3、运行


 

一、自由抒发

多线程编程时,我们可能需要对一个共享资源进行访问,如果资源是只读的,那便不存在不一致的问题,但共享访问的资源是可读可写的,例如想实现一个生产者消费者模型,那就需要提供一种同步机制,来保障各个线程每次拿到的数据是正确的。最基本的同步方式有:互斥执行、条件同步、栅栏同步。这三种应该对着不同的场景:

名称描述
互斥执行两个线程顺序的访问共享资源。
条件同步线程必须等待某个事件发生,才能去访问共享资源。
栅栏同步控制线程执行过程中的汇合。

二、函数介绍

 1、pthread_mutex_init

(1)声明

int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);

(2)作用

初始化互斥锁。

(3)参数

参数名描述
mutex需要初始化的互斥锁变量。
attr互斥锁的属性。NULL的话,互斥锁会被初始化为系统默认属性。

(4)返回值

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

(5)注意点

一个互斥变量只能被pthread_mutex_init函数初始化一次,如果初始化多次,有的系统会提示错误,但Linux系统会正常运行,需多注意。

(6)宏

 2、pthread_mutex_destroy

(1)声明

int pthread_mutex_destroy(pthread_mutex_t *mutex);

(2)作用

销毁互斥锁。

(3)参数

参数名描述
mutex需要销毁的互斥锁变量。

(4)返回值

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

(5)注意点

(6)宏

 3、pthread_mutexattr_init

(1)声明

int pthread_mutexattr_init(pthread_mutexattr_t *attr);

(2)作用

初始化互斥锁属性。

(3)参数

参数名描述
attr需要初始化的互斥锁属性变量。

(4)返回值

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

(5)注意点

(6)宏

 4、pthread_mutexattr_destroy

(1)声明

int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);

(2)作用

销毁互斥锁属性。

(3)参数

参数名描述
attr需要销毁的互斥锁属性变量。

(4)返回值

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

(5)注意点

(6)宏

 5、pthread_mutexattr_getpshared

(1)声明

int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict attr, int *restrict pshared);

(2)作用

获取互斥变量进程共享属性值。

(3)参数

参数名描述
attr需要获取的互斥锁属性变量。
pshared获取到的互斥变量进程共享属性值。

(4)返回值

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

(5)注意点

(6)宏

见pthread_mutexattr_init函数的相关宏。

 6、pthread_mutexattr_setpshared

(1)声明

int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared);

(2)作用

设置互斥变量进程共享属性值。

(3)参数

参数名描述
attr需要设置的互斥锁属性变量。
pshared设置的互斥变量进程共享属性值。

(4)返回值

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

(5)注意点

(6)宏

互斥变量进程共享属性值
描述
PTHREAD_PROCESS_PRIVATE只有同一个进程中的线程使用,默认值。
PTHREAD_PROCESS_SHARED可以多个进程的线程使用。

 7、pthread_mutexattr_gettype

(1)声明

int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict attr, int *restrict type);

(2)作用

获取互斥变量类型属性值。

(3)参数

参数名描述
attr需要获取的互斥锁属性变量。
type获取到的互斥变量类型属性值。

(4)返回值

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

(5)注意点

(6)宏

见pthread_mutexattr_init函数的相关宏。

 8、pthread_mutexattr_settype

(1)声明

int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);

(2)作用

设置互斥变量类型属性值。

(3)参数

参数名描述
attr需要设置的互斥锁属性变量。
type设置的互斥变量类型属性值。

(4)返回值

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

(5)注意点

(6)宏

互斥变量类型属性值
描述
PTHREAD_MUTEX_DEFAULT默认类型,标准规定可以是以下任意类型,也可以是完全不同的类型。Linux 3.2.0映射为PTHREAD_MUTEX_NORMAL,FreeBSD 8.0映射为PTHREAD_MUTEX_ERRORCHECK。
PTHREAD_MUTEX_NORMAL基本类型,无内建的特定错误和死锁检测,但也是最快的一种。
PTHREAD_MUTEX_RECURSIVE递归类型,允许同一个线程对其解锁之前进行多次加锁,为了释放此变量,需对其解锁相同次数。解锁和加锁次数不同的情况下,不会释放锁。
PTHREAD_MUTEX_ERRORCHECK提供错误检测功能。效率上比PTHREAD_MUTEX_NORMAL低很多,主要用于调试代码。

 

互斥量类型行为
互斥量类型锁拥有者没有解锁时重复加锁锁未持有者解锁解锁状态重复解锁
PTHREAD_MUTEX_DEFAULT未知未知未知
PTHREAD_MUTEX_NORMAL死锁未知未知
PTHREAD_MUTEX_RECURSIVE允许报错报错
PTHREAD_MUTEX_ERRORCHECK报错报错报错

  9、pthread_mutexattr_getrobust

(1)声明

int pthread_mutexattr_getrobust(const pthread_mutexattr_t *__attr, int *__robustness)
;

(2)作用

获取互斥变量健壮属性值。

(3)参数

参数名描述
__attr需要获取的互斥锁属性变量。
__robustness获取到的互斥变量健壮属性值。

(4)返回值

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

(5)注意点

(6)宏

见pthread_mutexattr_init函数的相关宏。

  10、pthread_mutexattr_setrobust

(1)声明

int pthread_mutexattr_setrobust(pthread_mutexattr_t *__attr, int __robustness)
;

(2)作用

设置互斥变量健壮属性值。

(3)参数

参数名描述
__attr需要设置的互斥锁属性变量。
__robustness设置的互斥变量健壮属性值。

(4)返回值

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

(5)注意点

(6)宏

互斥变量健壮属性值
描述
PTHREAD_MUTEX_STALLED持有互斥锁的进程终止时不需要采取特别的动作,等待互斥锁解锁的程序会被卡住,默认值。
PTHREAD_MUTEX_ROBUST这个用于处理这样的场景,两个进程都尝试获取互斥锁,第一个进程获取到了锁,在其还没有解锁之前,异常退出了,第二个进程如果使用PTHREAD_MUTEX_STALLED会卡住,而使用PTHREAD_MUTEX_ROBUST,第二进程的pthread_mutex_lock函数会返回EOWNERDEAD,我们可以根据其返回值来恢复互斥锁。

  11、pthread_mutex_consistent

(1)声明

int pthread_mutex_consistent(pthread_mutex_t *__mutex);

(2)作用

将健壮性互斥锁保护的状态标记为一致。

这个函数需要结合pthread_mutexattr_setrobust一起使用。

这个用于处理这样的场景,两个进程都尝试获取互斥锁,第一个进程获取到了锁,在其还没有解锁之前,异常退出了,第二个进程如果使用PTHREAD_MUTEX_STALLED会卡住,而使用PTHREAD_MUTEX_ROBUST。第二进程的pthread_mutex_lock函数会返回EOWNERDEAD,一般来说这个锁不是本进程或本线程上的锁,是不能进行解锁的,调用pthread_mutex_consistent之后,就可以进行解锁,解决了如何用Xsi Ipc共享内存加多线程互斥锁实现进程间的消费者生产者模型的问题。后面实现了这种组合用法,和大家分享一下。

(3)参数

参数名描述
__mutex需要设置的互斥锁属性变量。

(4)返回值

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

(5)注意点

(6)宏

见pthread_mutexattr_init函数的相关宏。

 12、pthread_mutex_lock

(1)声明

int pthread_mutex_lock(pthread_mutex_t *mutex);

(2)作用

对互斥变量进行加锁。

(3)参数

参数名描述
mutex需要加锁的互斥变量。

(4)返回值

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

(5)注意点

如果是互斥锁是PTHREAD_MUTEX_NORMAL类型,则该函数不会进行死锁检测,重复进行加锁,会导致死锁。

(6)宏

 13、pthread_mutex_unlock

(1)声明

int pthread_mutex_unlock(pthread_mutex_t *mutex);

(2)作用

对互斥变量进行解锁。

(3)参数

参数名描述
mutex需要解锁的互斥变量。

(4)返回值

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

(5)注意点

如果是互斥锁是PTHREAD_MUTEX_NORMAL类型,则该函数不会进行死锁检测,重复进行加锁,会导致死锁。

(6)宏

  14、pthread_mutex_trylock

(1)声明

int pthread_mutex_trylock(pthread_mutex_t *__mutex);

(2)作用

对互斥变量尝试进行加锁。

(3)参数

参数名描述
mutex需要加锁的互斥变量。

(4)返回值

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

(5)注意点

如果不能立马拿到互斥锁,会返回EBUSY宏。与pthread_mutex_lock不同,不会一直阻塞在那里。

(6)宏

  15、pthread_mutex_timedlock

(1)声明

int pthread_mutex_timedlock(pthread_mutex_t *__restrict__ __mutex, const struct timespec *__restrict__ __abstime);

(2)作用

对互斥变量进行加锁,在指定时间内未拿到锁返回特定宏。

(3)参数

参数名描述
mutex需要加锁的互斥变量。
__abstime指定时间内拿到锁。

 

(4)返回值

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

(5)注意点

对互斥变量进行加锁,在指定时间内未拿到锁会返回ETIMEDOUT。

(6)宏

三、如何避免死锁

1、重复加锁

同一个线程对一个互斥量加锁两次,那么它自身便会陷入死锁状态,如果互斥锁类型属性设置的是PTHREAD_MUTEX_ERRORCHECK便会报错。

2、互持锁

a和b两个线程,1和2两把互斥锁,a拿锁的顺序是1、2,b拿锁的顺序是2、1。就会导致死锁,如果它们拿锁的顺序是一致的,就可以避免这种情况的发生。

四、测试与练习

1、部分demo源码

三个线程对全局变量进行累加,和为18,表示测试正常。

我这边只是对于线程、线程属性、互斥锁、互斥锁属性做了简单封装,方便使用,如果大家感兴趣的话,可以在留言,我后面找一章分享出来。

#include "MyThread.h"#define THRD_ARRAY_LEN 3
#define SUM_VAL        (18 / 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_TIMED_LOCK_F(Mutex) == SUCCESS_FLAG){GlobalCnt++;THRD_MUTEX_UNLOCK_F(Mutex);}        }THRD_EXIT(NORMAL_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_ROBUST,1,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(Debug,"GlobalCnt          : %d.\n",GlobalCnt);return SUCCESS_FLAG;
}

2、编译

[gbase@czg2 Pthread]$ make clean
rm -rf Test
[gbase@czg2 Pthread]$ make
gcc -Wall -Wextra -O3 -std=gnu11  Test.c -o Test -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/Log/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/Pthread/  -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/SqQueue/ -L /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/Make/Libs/ -L /usr/lib64/ -l PublicFunction -l Log -l MyThread -l SqQueue

3、运行

[gbase@czg2 Pthread]$ perf stat -e page-faults ./Test 
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdMutexAttrInit  : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-MutexAttrSetShrd   : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-MutexAttrSetType   : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-MutexAttrSetRobust : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdMutexInit      : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-MutexAttrGetShrd   : OK, SharedVal   : PTHREAD_PROCESS_PRIVATE.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-MutexAttrGetType   : OK, Type        : PTHREAD_MUTEX_ERRORCHECK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-MutexAttrGetRobust : OK, Robust      : PTHREAD_MUTEX_ROBUST.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdMutexAttrDstry : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-OneThrdMutexCreate : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdAttrInit       : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-SetDetachState     : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-SetStackSize       : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-SetGuardSize       : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdCreate         : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-GetDetachState     : OK, DetachState : PTHREAD_CREATE_JOINABLE.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-GetStackSize       : OK, StackSize   : 16384.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-GetGuardSize       : OK, GuardSize   : 4096.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdAttrDestroy    : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-OneThrdCreate      : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdAttrInit       : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-SetDetachState     : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-SetStackSize       : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-SetGuardSize       : OK.
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexUnLock    : OK.
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexUnLock    : OK.
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexUnLock    : OK.
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexUnLock    : OK.
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexUnLock    : OK.
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559549184]-[Debug]-ThrdMutexUnLock    : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdCreate         : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-GetDetachState     : OK, DetachState : PTHREAD_CREATE_JOINABLE.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-GetStackSize       : OK, StackSize   : 16384.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-GetGuardSize       : OK, GuardSize   : 4096.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdAttrDestroy    : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-OneThrdCreate      : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdAttrInit       : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-SetDetachState     : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-SetStackSize       : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-SetGuardSize       : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdCreate         : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-GetDetachState     : OK, DetachState : PTHREAD_CREATE_JOINABLE.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-GetStackSize       : OK, StackSize   : 16384.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-GetGuardSize       : OK, GuardSize   : 4096.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdAttrDestroy    : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-OneThrdCreate      : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdWait           : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdExitState      : 2.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-OneThrdFree        : OK.
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexUnLock    : OK.
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexUnLock    : OK.
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexUnLock    : OK.
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexUnLock    : OK.
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexUnLock    : OK.
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559508224]-[Debug]-ThrdMutexUnLock    : OK.
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexUnLock    : OK.
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexUnLock    : OK.
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexUnLock    : OK.
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexUnLock    : OK.
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexUnLock    : OK.
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexTimedLock : OK. Sec : 1, NanoSec : 0
2024-03-21 17:48:57-P[75602]-T[140670559528704]-[Debug]-ThrdMutexUnLock    : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdWait           : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdExitState      : 2.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-OneThrdFree        : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdWait           : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdExitState      : 2.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-OneThrdFree        : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-ThrdMutexDestroy   : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-OneThrdMutexFree   : OK.
2024-03-21 17:48:57-P[75602]-T[140670559557440]-[Debug]-GlobalCnt          : 18.Performance counter stats for './Test':242      page-faults:u                                               0.003729662 seconds time elapsed0.000000000 seconds user0.004194000 seconds sys

 

 

 

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

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

相关文章

【大数据】四、HDFS 基础操作

IDE 连接 在本地电脑上解压 hadoop.tar.gz&#xff0c;配置环境变量 之后 去github 上 把 winutil.exe 和 hadoop.dll 下载到 hadoop 的bin 文件夹下 再修改 etc/hadoop-env.cmd 中的 JDK 路径 我们使用 IDEA 打开一个 JAVA Maven项目&#xff0c;进行测试 注意&#xff0…

vue3 报错 require is not defined

问题 require is not defined 原因 vite 不支持require的用法&#xff0c; webpack是支持的 解决 方法一&#xff1a; 更改vite使用语法 vite官网 方法二 安装转换插件vite-plugin-require-transform 仓库地址 参考 关于Vite不能使用require问题 方法二Vite 踩坑 —— …

一文详解大数据时代与低代码开发应用

随着信息技术的飞速发展&#xff0c;我们迎来了一个崭新的时代——大数据时代。在这个时代&#xff0c;数据成为了一种新的资源&#xff0c;大数据技术的应用成为了推动社会进步的关键力量。而在大数据技术的浪潮中&#xff0c;低代码开发应用也逐渐崭露头角&#xff0c;以其高…

鸿蒙开发-UI-动画-页面间动画

鸿蒙开发-UI-组件导航-Navigation 鸿蒙开发-UI-组件导航-Tabs 鸿蒙开发-UI-图形-图片 鸿蒙开发-UI-图形-绘制几何图形 鸿蒙开发-UI-图形-绘制自定义图形 鸿蒙开发-UI-图形-页面内动画 鸿蒙开发-UI-图形-组件内转场动画 鸿蒙开发-UI-图形-弹簧曲线动画 文章目录 前言 一、放大缩…

【TD3思路及代码】【自用笔记】

1 组成&#xff08;Target Network Delayed Training&#xff09; Actor网络&#xff1a;这个网络负责根据当前的状态输出动作值。在训练过程中&#xff0c;Actor网络会不断地学习和优化&#xff0c;以输出更合适的动作。Critic网络&#xff1a;TD3中有两个Critic网络&#xff…

【LeetCode-22.括号生成】

题目详情&#xff1a; 数字 n 代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且 有效的 括号组合。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;["((()))","(()())","(())()","()(…

第十四章 TypeScript tsconfig.json配置文件

生成tsconfig.json 文件 这个文件是通过tsc --init命令生成的 配置详解 "compilerOptions": {"incremental": true, // TS编译器在第一次编译之后会生成一个存储编译信息的文件&#xff0c;第二次编译会在第一次的基础上进行增量编译&#xff0c;可以提…

自然拼读-26个字母发音

自然拼读-26个字母发音 26个字母 Aa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz 元音和辅音 辅音 元音 单词 元音 Aa Ee Li Oo Uu 另外&#xff1a;Yy是半元音 辅音 Bb Cc Dd Ff Gg Hh Jj Kk Ll Mm Nn Pp Qq Rr Ss Tt Vv Ww X…

利用二分法求方程在某个范围内的根

问题描述&#xff1a; 利用二分法求方程在&#xff08;-10,10&#xff09;的根。 方法&#xff1a;先求出两端点的中点&#xff0c;然后将中点带入方程中检查是否等于0&#xff0c;如果等于0说明找到了根&#xff0c;如果大于0&#xff0c;说明根在左半部分&#xff0c;将rig…

Linux-网络层IP协议、链路层以太网协议解析

目录 网络层&#xff1a;IP协议地址管理路由选择 链路层 网络层&#xff1a; 网络层&#xff1a;负责地址管理与路由选择 — IP协议&#xff0c;地址管理&#xff0c;路由选择 IP协议 数据格式&#xff1a; 4位协议版本&#xff1a;4-ipv4协议版本 4位首部长度&#xff1a;以…

2024计算机二级Python 11和12

单向列表不能再回头&#xff0c;只有从头指针开始才可以&#xff0c;双向列表会出现重复访问&#xff0c;二叉树节点从根开始可以达到目的 面向对象的主要特征&#xff1a;抽象、封装、继承、多态 Python通过解释方式执行&#xff0c;执行速度没有采用编译方式的语言执行的快 f…

为什么线程通信的方法 wait(), notify()和 notifyAll()被定义在 Object 类里?为什么他们必须在同步方法或者同步块中被调用?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 为什么线程通信的方法 wait(), notify()和 notifyAll()被定义在 Object 类里 线程通信的方法wait()、notify()和notifyAll()被定义在Object类中的原因是因…

如何理解35岁是道门槛

先抛出观点&#xff0c;35岁是道门槛纯粹是以讹传讹&#xff0c;加上媒体的大力宣传&#xff0c;给更多的人加上了思想枷锁。而这&#xff0c;仿佛成为一种共识。 据个人观察&#xff0c;35岁焦虑是从互联网大厂那边传出来的。但估计很多人没有思考过背后的逻辑。12~18年&…

混合像元分解:Matlab如何帮助揭示地表组成?

光谱和图像是人们观察世界的两种方式&#xff0c;高光谱遥感通过“图谱合一”的技术创新将两者结合起来&#xff0c;大大提高了人们对客观世界的认知能力&#xff0c;本来在宽波段遥感中不可探测的物质&#xff0c;在高光谱遥感中能被探测。以高光谱遥感为核心&#xff0c;构建…

c++21,22多肽

普通人买全价&#xff0c;学生半价 多肽 构成条件 1.虚函数重写 2.父类的指针或者引用去调用虚函数 两个virtual没有关联 函数前面增加virtual虚函数&#xff0c;p是父类的引用&#xff0c;既可以传父类对象也可以传子类对象 去掉引用&#xff08;子类传给父类&#xff…

云手机为电商提供五大出海优势

出海电商行业中&#xff0c;各大电商平台的账号安全是每一个电商运营者的重中之重&#xff0c;账号安全是第一生产力&#xff0c;也是店铺运营的基础。因此多平台多账号的防关联管理工具成了所有电商大卖家的必备工具。云手机最核心的优势就是账户安全体系&#xff0c;本文将对…

linux系统----------MySQL索引浅探索

目录 一、数据库索引介绍 二、索引的作用 索引的副作用 (缺点) 三、创建索引的原则依据 四、索引的分类和创建 4.1普通索引 4.1.1直接创建索引 4.1.2修改表方式创建 4.1.3创建表的时候指定索引 4.2唯一索引 4.2.1直接创建唯一索引 4.2.2修改表方式创建 4.2.3创建表…

Go语言hash库完全教程:从基础到高级应用

Go语言hash库完全教程&#xff1a;从基础到高级应用 简介hash库概览hash接口常用的哈希函数实现应用场景性能特点字符串哈希计算 使用hash库进行数据哈希文件哈希计算 hash库在数据校验中的应用使用SHA256进行文件完整性验证 hash库在安全加密中的应用生成安全的密码哈希使用HM…

cmd窗口运行jar程序,点击一下cmd窗口后java程序就暂停了

cmd窗口运行jar程序时&#xff0c;在cmd窗口点击了一下&#xff0c;如果你选中了&#xff08;页面会有个白色的选中内容&#xff09;&#xff0c;java程序就会暂停&#xff0c;这是只有按一下鼠标右键或着CtrlC才能取消选中&#xff0c;程序才会继续运行&#xff0c;如果java程…

学习笔记 | 微信小程序项目day06

今日学习内容 商品详情页 商品详情页 1、定义类型 import type { GoodsItem } from ./global/** 商品信息 */ export type GoodsResult {/** id */id: string/** 商品名称 */name: string/** 商品描述 */desc: string/** 当前价格 */price: number/** 原价 */oldPrice: nu…