ankikong

  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

几种锁

发表于 2020-02-03 更新于 2023-02-26

互斥锁

某一时刻最多只有一个线程能获得互斥锁

自旋锁

一种特殊的互斥锁,获取不到锁时,不是直接进入阻塞队列等待唤醒,而是进入循环等待状态(占用CPU),循环询问能否获得锁,具有高响应,但是占用大量CPU资源

读写锁

读写锁某一时刻只能被一条线程获得写锁或者同时被多条线程获得读锁.
读写,写写互斥.读读可同时进行

悲观锁

在每次读取数据时都认为会有人更改数据,所以每次读取数据时都会加锁.
很多传统关系型数据库就使用了这个锁,

乐观锁

在每次读取数据时都认为不会有人更改数据,所以每次读取数据时都不会加锁.在更新时会判断一下是否有其他线程更改了数据,是的话返回错误,具体操作有开发人员决定

learning bash

发表于 2020-02-03 更新于 2023-02-26

变量

  • 变量定义和赋值,变量名和赋值符号和值之间不能有空格
  • 变量名规则和c语言要求一致
  • 使用已定义的变量用$引用,如$FUCK或${FUCK},花括号只起边界作用
  • 可以使用readonly xxxx,将xxxx设置为只读变量,只读变量不允许修改和删除
  • unset可以删除变量
  • 字符串
    • 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
    • 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
    • 双引号里可以有变量
    • 双引号里可以出现转义字符
    • 字符串可以直接拼接"ahh"${agg}"ahhhh"
    • 子串${string:1:2}
    • 串长
      1
      2
      3
      4
      5
      6
      - 数组
      - 只支持一维数组
      - 定义`a=(var1 var2 var3)`
      - `a[n]=111`
      - 读取数组`$(a[n])`,使用`@`可以获取数组全部元素
      - 数组长度```${#a[*]}

传参

$0: 可执行文件文件名
$#: 传递参数数量
$*: 传递的所有参数
$$: 当前运行脚本的PID
$@: 和$*一样
$-: 显示Shell使用的当前选项
$?: 最后命令的退出状态。0表示没有错误,其他任何值表明有错误

中括号

  • 算术比较, 比如一个变量是否为0, [ $var -eq 0 ]
    • -eq 相等
    • -ne 不等
    • -gt 大于
    • -lt 小于
    • -ge 大于或等于
    • -le 小于或等于
  • 文件属性测试,比如一个文件是否存在,[ -e $var ]
    • -b 是否块设备文件
    • -c 是否字符设备文件
    • -d 是否目录
    • -e 文件是否存在
    • -f 正常文件路径或文件名
    • -x 可执行文件
    • -L 是否符号连接
    • -r 是否可读
    • -w 是否可写
  • 字符串比较
    • 两个字符串是否相同 [[ $var1 = $var2 ]],test $var1 = $var2
    • 两个字符串是否不同 [[ $var1 != $var2 ]]
    • 是否空串 [[ -z $str1 ]]
    • 是否非空串 [[ -n $str1 ]]

运算符

  • 布尔运算
    • ! 非
    • -o,|| 或
    • -a,&& 与

printf

printf format-string [arguments...]

  • 格式化方式和c语言的printf一致

控制

if

1
2
3
4
5
6
7
8
9
10
11
12
13
14
a=10
b=20
if [ $a == $b ]
then
echo "a 等于 b"
elif [ $a -gt $b ]
then
echo "a 大于 b"
elif [ $a -lt $b ]
then
echo "a 小于 b"
else
echo "没有符合的条件"
fi

for

1
2
3
4
5
6
7
8
9
10
11
12
13
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
####################################
for((assignment;condition:next));do
command_1;
command_2;
commond_..;
done;

while

1
2
3
4
while condition
do
command
done

case

1
2
3
4
5
6
7
8
9
10
case 值 in
模式1)
...
commandN
;;
模式2)
...
commandN
;;
esac

函数

参数获取方式和cmd的参数获取一致

1
2
3
4
5
[ function ] funname [()]
{
action;
[return int;]
}

输入输出重定向

  • command > file 将输出重定向到 file
  • command < file 将输入重定向到 file
  • 文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)

docker学习笔记

发表于 2020-02-02 更新于 2023-02-26

构建时的相对路径

docker build . 并不是指定dockerfile的路径,而是指定了构建时ADD和COPY的上下文路径,然后根据这个路径将文件加入&复制到镜像中

DOCKERFILE

FROM

  • FROM是指定的基础镜像,构建时在基础镜像之上操作
  • 必须是第一条指令

RUN

RUN是在构建镜时执行一次的shell脚本

  • 一个RUN对应一个UNION FS层,因此,一般RUN多条指令用 && 连接,而不是多个RUN

COPY

  • COPY的目的路径既可以是镜像的绝对路径,也可以是相对路径(相对于WORKDIR)
  • COPY会保留文件的各种元数据,包括权限,时间戳等
  • 可以加上--chown=<user>:<group>修改目标权限 COPY --chown=55:mygroup files* /mydir/

ADD

  • 可以ADD URL,将链接文件下载到指定位置,然后设置权限600
  • ADD一个压缩文件,则会自动解压到指定目录

CMD

  • 容器开启时使用的命令
  • 由于CMD一结束,docker容器也会一起停止运行,所以CMD执行服务的话,要让任务在前台运行

ENTRYPOINT

  • docker run xxx 时,会把后面的参数传递给ENTRYPOINT

ENV

  • 设置容器运行时环境变量,有两种格式
  • ENV <key> <value>
  • ENV <key1>=<value1> <key2>=<value2>...

ARG

  • 设置构建容器时的环境变量
  • 可以使用--build-arg <参数名>=<值>在执行时加入

VOLUME

  • 容器写操作执行位置,应避免在容器的存储层写数据

EXPOSE

  • 声明端口,但运行时不会在宿主进行端口映射

WORKDIR

  • 指定工作目录

USER

  • 指定当前用户,用户必须提前创建

HEALTHCHECK

  • 健康检查,告诉docker应该如何判断容器是否正常
  • HEALTHCHECK 支持下列选项:
    • --interval=<间隔>:两次健康检查的间隔,默认为 30 秒;
    • --timeout=<时长>:健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒;
    • --retries=<次数>:当连续失败指定次数后,则将容器状态视为 unhealthy,默认 3 次。

ONBUILD

  • ONBUILD 是一个特殊的指令,它后面跟的是其它指令,比如 RUN, COPY 等,而这些指令,在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行

操作容器

启动容器

新建并启动

  • 所需要的命令主要为 docker run

启动已终止容器

  • docker container start

POSIX semaphore

发表于 2020-02-02 更新于 2023-02-26

无名信号量

  • 除非使用共享内存,否则只能控制通同一进程的线程
1
2
3
4
// 初始化信号量sem的初始值为value
int sem_init (sem_t *__sem, int __pshared, unsigned int __value)
// 删除信号量
int sem_destroy (sem_t *__sem)

有名信号量

1
2
3
4
5
6
7
8
9
10
11
// name是名称
// oflag:O_CREAT:如果信号量不存在则新建,存在直接返回
// 如果为O_CREAT|O_EXCL,则已存在的话会返回错误
// mode:
// value:初始值
sem_t *sem_open(const char *name, int oflag);
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
// 关闭进程内信号量
int sem_close (sem_t *__sem)
// 从内核中删除有名信号量
int sem_unlink (const char *__name)

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
int pid = fork();
if (pid<0) {
cout << "fork failed";
}
if (pid==0) {
sem_t* sem=sem_open("test", O_CREAT, 0666, 1);
int rs = sem_wait(sem);
if (rs<0) {
cout << "wait failed";
exit(-1);
} else {
cout << "success 1" << endl;
sleep(3);
sem_post(sem);
sem_close(sem);
}
} else {
sem_t* sem=sem_open("test", O_CREAT, 0666, 1);
int rs=sem_wait(sem);
if (rs<0) {
cout << "wait failed";
exit(-1);
} else {
cout << "success 2" << endl;
sleep(3);
sem_post(sem);
sem_close(sem);
}
int tmp;
wait(&tmp);
}

共用操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 阻塞获取,值-1
int sem_wait (sem_t *__sem)
// 阻塞超时获取
int sem_timedwait (sem_t *__restrict __sem, const struct timespec *__restrict __abstime)
struct timespec {
__time_t tv_sec; // Seconds
__syscall_slong_t tv_nsec; // Nanoseconds
};
// 非阻塞获取信号量,成功放回0,值-1;失败返回-1
// EINTR:信号处理函数中断调用
// EINVAL:信号量sem值无效
// EAGAIN:信号量不足
int sem_trywait (sem_t *__sem)
// 释放信号量,值+1
int sem_post (sem_t *__sem)
// 获取当前信号量的值,存在sval
int sem_getvalue (sem_t *__restrict __sem, int *__restrict __sval)

参考文献

  • Linux Programmer’s Manual
  • Linux信号量

Linux-IPC

发表于 2020-01-29 更新于 2023-02-26

进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。IPC的方式通常有管道(包括无名管道和命名管道)、消息队列、信号量、共享存储、信号、Socket、Streams等。其中 Socket和Streams支持不同主机上的两个进程IPC

阅读全文 »

cpp

发表于 2020-01-18 更新于 2023-02-26

c++学习日志

阅读全文 »

install wsl on a non-system drive

发表于 2019-11-23 更新于 2023-02-26

网上好像用软链的方法挺多的,今天不是用软链方式(主要是我失败了)

阅读全文 »

MySql-Password

发表于 2019-10-24 更新于 2023-02-26

老生常谈的问题

阅读全文 »

create hostapd with ipv4&6 support

发表于 2019-09-06 更新于 2023-02-26

捣鼓了这么久,总算是实现在树莓派3b上开启支持ipv4和ipv6的热点,真是不容易,网上各种傻x桥接,根本跑不起来,看着都气人。

阅读全文 »

banzi

发表于 2019-08-16 更新于 2023-02-26

simpson

1
2
3
4
5
6
7
8
9
10
double work(double L,double R){
double mid=(L+R)/2;
return (f(L)+f(R)+f(mid)*4)*(R-L)/6;
}
double simpson(double L,double R){
double mid=(L+R)/2;
double x1=work(L,mid),x2=work(mid,R),x3=work(L,R);
if (std::fabs(x1+x2-x3)<eps) return x1+x2;
else return simpson(L,mid)+simpson(mid,R);
}
阅读全文 »
1234

ankikong

ankikong's blog
31 日志
25 标签
GitHub E-Mail
© 2023 ankikong
由 Hexo 强力驱动 v3.9.0
|
主题 – NexT.Gemini v7.3.0