• Linux信号量操作次数的探究


      需求源于项目中一部分设计的代码。struct semaphore类型的信号量,使用up()进行释放,down_interruptible()和down()获得指定信号量(前者中,若该信号量已争用则进入可中断睡眠,后者进入不可中断睡眠)。

      理想中的流程应该是线程调用down()阻塞一个信号量,等待另一个线程调用up()释放,从而实现同步。但如果另一个线程使用up()释放多次,会有怎样的结果呢?LKD上没有进行详细的解释,我使用一个简单的测试程序,其中的核心代码如下:

    /* A线程,释放信号量 */
    while(!kthread_should_stop())
    {
    up(
    &my_sem);
    set_current_state(TASK_INTERRUPTIBLE);
    SLEEP_MILLI_SEC(
    2000); //睡眠宏,以ms为单位
    }


    /* B线程,获得信号量 */
    while(!kthread_should_stop())
    {
    down_interruptible(
    &my_sem);
    struct timeval t;
    do_gettimeofday(
    &t);
    printk(
    "Time is:%ld %ld\n", t.tv_sec, t.tv_usec);
    }

      这时的行为是:每隔2s打印一次时间。

      当把A线程改为一次释放两次时,输出发生了改变:

     [ 7357.645663] Time is: 1342870729 491558
    [ 7357.645667] Time is: 1342870729 491574
    [ 7359.646921] Time is: 1342870731 492824
    [ 7359.646925] Time is: 1342870731 492830
    [ 7361.644350] Time is: 1342870733 490254
    [ 7361.644353] Time is: 1342870733 490259
    [ 7363.644699] Time is: 1342870735 490602
    [ 7363.644703] Time is: 1342870735 490609

      可以看出,A线程每2秒释放两次,结果使得B线程每2秒打印两次,两次打印相当于无间隔。

      继续修改,每2秒A线程up()操作3次然后睡眠,B线程一次循环down_interruptible()操作2次后进行输出,下面是最初一部分的内核输出。

    [ 7983.526972] Time is: 1342871355 372854
    [ 7985.524609] Time is: 1342871357 370512
    [ 7985.524654] Time is: 1342871357 370559
    [ 7987.524217] Time is: 1342871359 370119
    [ 7989.524138] Time is: 1342871361 370041
    [ 7989.524142] Time is: 1342871361 370047
    [ 7991.524454] Time is: 1342871363 370357
    [ 7993.525012] Time is: 1342871365 370914
    [ 7993.525017] Time is: 1342871365 370923
    [ 7995.524760] Time is: 1342871367 370663

       分析如下:A第一次释放了3个资源,B攒够2个进行第一次输出,多余的1个虽已申请,但还差1个;2秒后A又释放了3个,B一下子攒够了4个,进行两次连续的输出。此后如此循环。

      可以看出,这种信号量不是非0即1的二值信号量,如果释放过多而又不能及时消耗,很有可能造成数据溢出和宕机。

  • 相关阅读:
    Java基于Socket文件传输示例
    mysql 改变编码
    POI应用:利用word模板批量生成word文档(java中word文档的读写)
    Win 7—FTP服务器配置
    Chrome 快捷键
    JAVA中使用FTPClient上传下载 java利用ftp协议上传文件(by me)
    JAVA中使用FTPClient上传下载
    如何去除TD之间的空隙
    较丰富的教程
    输入年月 返回当月天数.html
  • 原文地址:https://www.cnblogs.com/wuyuegb2312/p/2602900.html
Copyright © 2020-2023  润新知