shell 指令后加&后没有实现并发原因分析

复现程序

#!/bin/bash

cd /tmp
fallocate -l 256M  disk
mkfs.ext4 disk
nbd-server 8000 /tmp/disk


nbd-client -d /dev/nbd0

nbd-client localhost 8000 /dev/nbd0
sleep 1s
nbd-client -d /dev/nbd0 &             #后台执行,让第二次connect立即开始

nbd-client localhost 8000 /dev/nbd0

rm -f disk

第二次connect并没有在disconnect阻塞期间就开始执行,为什么?

测试用例本身没有问题,是disconnect这个进程中持有资源,然后connect进程正好需要这个资源,所以导致connect这个进程必须等待disconnect进程结束之后才可以执行。
 

具体的代码分析如下;

建立连接会调用:nbd_genl_connect

断开连接胡调用:nbd_genl_disconnect


driver/block/nbd.c中:
//建立连接和断开连接都是同一个doit,都在genl_family_rcv_msg被调用,

  2100 static const struct genl_ops nbd_connect_genl_ops[] = {
  2101     {
  2102         .cmd    = NBD_CMD_CONNECT,
  2103         .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  2104         .doit   = nbd_genl_connect,                                                                                                                              
  2105     },
  2106     {
  2107         .cmd    = NBD_CMD_DISCONNECT,
  2108         .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  2109         .doit   = nbd_genl_disconnect,
  2110     },
  2111     {
  2112         .cmd    = NBD_CMD_RECONFIGURE,
  2113         .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  2114         .doit   = nbd_genl_reconfigure,
  2115     },
  2116     {
  2117         .cmd    = NBD_CMD_STATUS,
  2118         .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  2119         .doit   = nbd_genl_status,
  2120     },  
  2121 };

 

net/netlink/genetlink.c

genl_rcv_msg
    genl_family_rcv_msg
        err = ops->doit(skb, &info);

net/netlink/genetlink.c中

 641 static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
 642             struct netlink_ext_ack *extack)
 643 {
 644     const struct genl_family *family;
 645     int err;
 646 
 647     family = genl_family_find_byid(nlh->nlmsg_type);
 648     if (family == NULL)
 649         return -ENOENT;
 650 
 651     if (!family->parallel_ops)             //判断是否允许并行,不允许,就会上锁
 652         genl_lock();                       //所以造成了不能并行,导致我的测试脚本中的
 653 
 654     err = genl_family_rcv_msg(family, skb, nlh, extack); //connect和disconnect都是通过这里调用
 655 
 656     if (!family->parallel_ops)
 657         genl_unlock();                      //解锁
 658 
 659     return err;
 660 }

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用shell脚本 gnuplot画图,你可以按照以下步骤进行操作: 1. 首先,你需要将数据保存为一个文本文件,比如netstat.txt。你可以使用命令将数据重定向到文件中,例如: ``` netstat > netstat.txt ``` 2. 接下来,你需要进入gnuplot绘图命令模式。你可以在终端中输入`gnuplot`命令来进入绘图模式。 3. 在gnuplot绘图命令模式下,你可以使用`load`命令载刚才保存的数据文件,比如: ``` load "netstat.txt" ``` 4. 此外,你还可以在shell模式下使用gnuplot绘图指令来生成图形。比如,你可以使用以下指令设置终端、输出文件、标题、坐标轴等属性: ``` set terminal png size 1400,700 font "/usr/share/fonts/kingsoft/simfang.ttf,14" set output "ab测试结果.png" set title "ab测试" set size 1,0.8 set grid y set xlabel "并发" set xrange [0:2000] set ylabel "响应时间(ms)" set yrange [0:100] set ytics nomirror set y2label "吞吐率" set y2tics ``` 5. 最后,你可以使用`plot`命令来绘制图形。你可以指定要使用的数据文件、要绘制的曲线类型、点形状和标题等。例如: ``` plot "ab-result.dat" using 1:4 smooth sbezier with linespoint pointtype 2 title "吞吐率", \ "ab-result.dat" using 1:3 smooth sbezier with linespoint pointtype 3 axis x1y2 title "响应时间/y2轴" ``` 这样,你就可以使用shell脚本 gnuplot画图了。记得根据你的具体需求和数据文件格式进行相应的调整。<span class="em">1</span><span class="em">2</span><span class="em">3</span>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值