精华内容
下载资源
问答
  • 转自:... 用上win7一段时间后,已经习惯了从任务栏直接点快捷方式打开ie和资源管理器,也把常用的一些程序的快捷方式锁定到了任务栏,方便使用最近不知道装什么软件影响了系统,程序和快捷方式都

    转自:http://www.7es.cn/ziliao-shoucang/135.shtml

    用上win7一段时间后,已经习惯了从任务栏直接点快捷方式打开ie和资源管理器,也把常用的一些程序的快捷方式锁定到了任务栏,方便使用。

    最近不知道装什么软件影响了系统,程序和快捷方式都无法附加到win7任务栏了,打开程序点右键也找不到“将此程序锁定到任务栏”一项菜单了。
    找了半天,据说有第三方软件可以设置,不过我不习惯用那些工具,还是自力更生了。
    找了好久,终于发现时注册表中某个项出现了问题。
    解决方法是,运行注册表(开始菜单里直接在搜索程序和文件框输入regedit然后回车即可打开),找到节点HKEY_CLASSES_ROOT下的lnkfile项,右面的isShortcut项的值应该是"",看清,是两个引号,表示空字符串,如果没有这个项,就手工添加一个字符串项进去。另外还有个HKEY_CLASSES_ROOT\piffile下也有同样一项,要做同样处理。
    然后打开任务管理器,结束进程explorer,再运行explorer,这样就生效了,看看是不是可以了点右键将程序锁定到windows7的任务栏了呢?
    不会操作注册表的朋友可以将如下文本复制粘贴,保存到文件abc.reg,就是一个注册表导入文件,然后双击执行导入该文件,结束再打开explorer即可。


    Windows Registry Editor Version 5.00

    [HKEY_CLASSES_ROOT\lnkfile]
    @="Shortcut"
    "IsShortcut"=""
    [HKEY_CLASSES_ROOT\piffile]
    @="Shortcut to MS-DOS Program"
    "IsShortcut"=""
    展开全文
  • 使用仿真器在线仿真,下程序后无法运行main函数,仿佛进入死循环。  在网上查了很多资料。试了一些方法。最终将问题锁定在启动程序中看门狗复位。解决办法是将IAR中的cstartup.s43(IAR Systems\Embedded ...

        作为新手最近遇到IAR编译程序Ok。使用仿真器在线仿真,下程序后无法运行到main函数,仿佛进入死循环。

        在网上查了很多资料。试了一些方法。最终将问题锁定在启动程序中看门狗复位。解决办法是将IAR中的cstartup.s43(IAR Systems\Embedded Workbench 8.0\430\src\lib\430)文件复制到自己的工程文件中,并添加进工程。在文件开头处添加#define DISABLE_WATCHDOG。让单片机在启动程序中不使能看门狗。

        我想之所以需要禁止启动程序中的看门狗程,应该与程序大小有关。初始化程序地址需要时间,程序越大初始化填值时间越长,超过看门狗时间,单片机就会复位。从而进入死循环。只是自己猜测。

    展开全文
  • 刚开始真的不知道发生了什么,后来一步一步的试,锁定在这个大的数组上。在主函数里定义的局部变量应该是在栈区保存的,难道是Qt默认的栈不够所致。 后来改为new或者malloc,也就是从堆里面申请内存,程序就没问题...

    【Qt开发】关于Qt应用程序中的堆栈、静态存储区的使用错误

    标签:【Qt开发】


    最近终于又碰到了这个问题,想在main函数中定义一个局部大的数组,结果运行就报错,尼玛!刚开始真的不知道到发生了什么,后来一步一步的试,锁定在这个大的数组上。在主函数里定义的局部变量应该是在栈区保存的,难道是Qt默认的栈不够所致。


    后来改为new或者malloc,也就是从堆里面申请内存,程序就没问题,或者是定义全局变量应该是放在了全局静态存储区,都是可以的,不报错!

    所以牢记这一点!!

    下面还是经典的经典内存分布说明:

    一、预备知识—程序的内存分配
    一个由c/C++编译的程序占用的内存分为以下几个部分
    1、栈区(stack)— 由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
    2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
    3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域(.data),未初始化的全局变量和未初始化的静态变量在相邻的另一块区域(.bss)。 - 程序结束后由系统释放。
    4、文字常量区 —常量字符串就是放在这里的(.rodata)。 程序结束后由系统释放。
    5、程序代码区—存放函数体的二进制代码(.text)。

    二、例子程序
    这是一个前辈写的,非常详细

    //main.cpp
    int a = 0;          // 全局初始化区
    char *p1;           // 全局未初始化区
    main()
    {
      int b;            // 栈区
      char s[] = "abc"; // 栈区
      char *p2;         // 栈区
      char *p3 = "123456";     // "123456/0" 在常量区,p3在栈区
      static int c =0;         // 全局(静态)初始化区
    
      p1 = (char *)malloc(10);
      p2 = (char *)malloc(20); // 分配得来的10和20字节的区域就在堆区
    
      strcpy(p1, "123456");    // "123456/0" 放在常量区,编译器可能会将它
                                  // 与p3所指向的"123456"优化成一个地方。
    } 

    ==============================================================
    static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?
    static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?   
    答:
    1) 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
    2) 从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。  
    3) static函数与普通函数作用域不同,仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件   
    综上所述:
    static全局变量与普通的全局变量有什么区别:
    static全局变量只初使化一次,防止在其他文件单元中被引用;   
    static局部变量和普通局部变量有什么区别:
    static局部变量只被初始化一次,下一次依据上一次结果值;   
    static函数与普通函数有什么区别:
    static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝

    ==============================================================
    一个C语言变量分配的实际例子:

    我们来看看在可执行文件中,变量们会被分配在哪些区里.这里以可执行文件为例子,可执行文件有固定的内存加载地址,符号(函数/变量的名字)将来在内存里的地址连接器是可以提前确定的。

    源程序编译连接的结果是形成1堆汇编指令代码,大致分为.text .data .bss等几个节区(section)。对于.exe文件和.so文件,全局和静态变量都放在.data 或.bss段(gas把源文件从头到尾扫描1遍,才知道一个变量的全部情况:是否定义;类型;是否初始化。然后把初始化的变量在.data段里分配位置和 空间,把没初始化的变量在.bss段里分配位置和空间,没定义的变量分配在.undef段)。汇编指令代码里全局变量表现为一个内存地址(全局变量在目标 文件里是一个偏移值,加载进内存里是一个内存地址)。临时变量在汇编代码里变成ebp/esp+n,表现为一个堆栈地址,化为程序正文(.text)的一 部分。有些变量的最终内存地址在加载进内存之前还不能确定,需要加载进内存才可以计算出来.
    全局变量 作用域是跨越多个源程序的。因此全局变量不能重名。静态变量作用域是位于单个源程序内。多个源程序可以有同名的全局静态变量。本例中,为了区分多个同名的静态变量,gcc 用 c444和c444.0 来加以区别。

    [test@redhat]# more aaa.c
    # include <stdio.h>
    int a111 = 0;              # 全局变量 已初始化
    char *p111 = "654321";     # 全局指针变量 已经初始化
    static int c444 = 9;       # 静态全局变量 已经初始化
    static int c555;           # 静态全局变量 未初始化
    main() 
    { 
        int b222;              # 局部变量
        char s333[] = "abc";   # 局部变量
        char *p222;            # 局部变量
        char *p333 = "123456";    # 局部变量
        static int c444 =0;       # 已初始化静态局部变量,与前面静态全局变量重名
    p111 = (char *)malloc(10); 
    p222 = (char *)malloc(20);
    strcpy(p111, "123456");
    

    }

    
    [test@redhat]# gcc -o aaa ./aaa.c
    
    [test@redhat]# readelf -a ./aaa
    ELF Header:
      Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
      Class:                             ELF32
      Data:                              2's complement, little endian
      Version:                           1 (current)
      OS/ABI:                            UNIX - System V
      ABI Version:                       0
      Type:                              EXEC (Executable file)
      Machine:                           Intel 80386
      Version:                           0x1
      Entry point address:               0x80482d0
      Start of program headers:          52 (bytes into file)
      Start of section headers:          2040 (bytes into file)
      Flags:                             0x0
      Size of this header:               52 (bytes)
      Size of program headers:           32 (bytes)
      Number of program headers:         7
      Size of section headers:           40 (bytes)
      Number of section headers:         27
      Section header string table index: 24

    Section Headers: Addr是文件加载进内存时,每个section在内存中的虚拟地址

      [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
      [ 0]                   NULL            00000000 000000 000000 00      0   0  0
      [ 1] .interp           PROGBITS        08048114 000114 000013 00   A  0   0  1
      [ 2] .note.ABI-tag     NOTE            08048128 000128 000020 00   A  0   0  4
      [ 3] .hash             HASH            08048148 000148 00002c 04   A  4   0  4
      [ 4] .dynsym           DYNSYM          08048174 000174 000060 10   A  5   1  4
      [ 5] .dynstr           STRTAB          080481d4 0001d4 000053 00   A  0   0  1
      [ 6] .gnu.version      VERSYM          08048228 000228 00000c 02   A  4   0  2
      [ 7] .gnu.version_r    VERNEED         08048234 000234 000020 00   A  5   1  4
      [ 8] .rel.dyn          REL             08048254 000254 000008 08   A  4   0  4
      [ 9] .rel.plt          REL             0804825c 00025c 000018 08   A  4   b  4
      [10] .init             PROGBITS        08048274 000274 000017 00  AX  0   0  4
      [11] .plt              PROGBITS        0804828c 00028c 000040 04  AX  0   0  4
      [12] .text             PROGBITS        080482d0 0002d0 0001e4 00  AX  0   0 16
      [13] .fini             PROGBITS        080484b4 0004b4 00001b 00  AX  0   0  4
      [14] .rodata           PROGBITS        080484d0 0004d0 00001a 00   A  0   0  4
      [15] .eh_frame         PROGBITS        080484ec 0004ec 000004 00   A  0   0  4
      [16] .data             PROGBITS        080494f0 0004f0 00001c 00  WA  0   0  4
      [17] .dynamic          DYNAMIC         0804950c 00050c 0000c8 08  WA  5   0  4
      [18] .ctors            PROGBITS        080495d4 0005d4 000008 00  WA  0   0  4
      [19] .dtors            PROGBITS        080495dc 0005dc 000008 00  WA  0   0  4
      [20] .jcr              PROGBITS        080495e4 0005e4 000004 00  WA  0   0  4
      [21] .got              PROGBITS        080495e8 0005e8 00001c 04  WA  0   0  4
      [22] .bss              NOBITS          08049604 000604 000008 00  WA  0   0  4
      [23] .comment          PROGBITS        00000000 000604 000126 00      0   0  1
      [24] .shstrtab         STRTAB          00000000 00072a 0000ce 00      0   0  1
      [25] .symtab           SYMTAB          00000000 000c30 0004c0 10     26  2f  4
      [26] .strtab           STRTAB          00000000 0010f0 000275 00      0   0  1
    Program Headers:
      Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
      PHDR           0x000034 0x08048034 0x08048034 0x000e0 0x000e0 R E 0x4
      INTERP         0x000114 0x08048114 0x08048114 0x00013 0x00013 R   0x1
          [Requesting program interpreter: /lib/ld-linux.so.2]
      LOAD           0x000000 0x08048000 0x08048000 0x004f0 0x004f0 R E 0x1000
      LOAD           0x0004f0 0x080494f0 0x080494f0 0x00114 0x0011c RW  0x1000
      DYNAMIC        0x00050c 0x0804950c 0x0804950c 0x000c8 0x000c8 RW  0x4
      NOTE           0x000128 0x08048128 0x08048128 0x00020 0x00020 R   0x4
      STACK          0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x4

    Symbol table ‘.symtab’ contains 76 entries:
    对于.exe文件,符号的Value 是将来加载进内存中的真实地址;对于.so文件Value需要重定位.

       Num:    Value  Size Type    Bind   Vis      Ndx Name
         0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
         1: 08048114     0 SECTION LOCAL  DEFAULT    1 
         2: 08048128     0 SECTION LOCAL  DEFAULT    2 
         3: 08048148     0 SECTION LOCAL  DEFAULT    3 
         4: 08048174     0 SECTION LOCAL  DEFAULT    4 
         5: 080481d4     0 SECTION LOCAL  DEFAULT    5 
         6: 08048228     0 SECTION LOCAL  DEFAULT    6 
         7: 08048234     0 SECTION LOCAL  DEFAULT    7 
         8: 08048254     0 SECTION LOCAL  DEFAULT    8 
         9: 0804825c     0 SECTION LOCAL  DEFAULT    9 
        10: 08048274     0 SECTION LOCAL  DEFAULT   10 
        11: 0804828c     0 SECTION LOCAL  DEFAULT   11 
        12: 080482d0     0 SECTION LOCAL  DEFAULT   12 
        13: 080484b4     0 SECTION LOCAL  DEFAULT   13 
        14: 080484d0     0 SECTION LOCAL  DEFAULT   14 
        15: 080484ec     0 SECTION LOCAL  DEFAULT   15 
        16: 080494f0     0 SECTION LOCAL  DEFAULT   16 
        17: 0804950c     0 SECTION LOCAL  DEFAULT   17 
        18: 080495d4     0 SECTION LOCAL  DEFAULT   18 
        19: 080495dc     0 SECTION LOCAL  DEFAULT   19 
        20: 080495e4     0 SECTION LOCAL  DEFAULT   20 
        21: 080495e8     0 SECTION LOCAL  DEFAULT   21 
        22: 08049604     0 SECTION LOCAL  DEFAULT   22 
        23: 00000000     0 SECTION LOCAL  DEFAULT   23 
        24: 00000000     0 SECTION LOCAL  DEFAULT   24 
        25: 00000000     0 SECTION LOCAL  DEFAULT   25 
        26: 00000000     0 SECTION LOCAL  DEFAULT   26 
        27: 080482f4     0 FUNC    LOCAL  DEFAULT   12 call_gmon_start
        28: 00000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
        29: 080495d4     0 OBJECT  LOCAL  DEFAULT   18 __CTOR_LIST__
        30: 080495dc     0 OBJECT  LOCAL  DEFAULT   19 __DTOR_LIST__
        31: 080484ec     0 OBJECT  LOCAL  DEFAULT   15 __EH_FRAME_BEGIN__
        32: 080495e4     0 OBJECT  LOCAL  DEFAULT   20 __JCR_LIST__
        33: 080494f8     0 OBJECT  LOCAL  DEFAULT   16 p.0
        34: 08049604     1 OBJECT  LOCAL  DEFAULT   22 completed.1
        35: 08048320     0 FUNC    LOCAL  DEFAULT   12 __do_global_dtors_aux
        36: 08048360     0 FUNC    LOCAL  DEFAULT   12 frame_dummy
        37: 00000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
        38: 080495d8     0 OBJECT  LOCAL  DEFAULT   18 __CTOR_END__
        39: 080495e0     0 OBJECT  LOCAL  DEFAULT   19 __DTOR_END__
        40: 080484ec     0 OBJECT  LOCAL  DEFAULT   15 __FRAME_END__
        41: 080495e4     0 OBJECT  LOCAL  DEFAULT   20 __JCR_END__
        42: 08048490     0 FUNC    LOCAL  DEFAULT   12 __do_global_ctors_aux
        43: 00000000     0 FILE    LOCAL  DEFAULT  ABS aaa.c
        44: 08049504     4 OBJECT  LOCAL  DEFAULT   16 c444   # static变量为LOCAL绑定属性(也即作用域) 已初始化静态变量存放在.data
        45: 08049508     4 OBJECT  LOCAL  DEFAULT   16 c444.0 # 已初始化静态变量存放在.data (多个源文件可以定义同名的静态变量)
        46: 08049608     4 OBJECT  LOCAL  DEFAULT   22 c555   # 未初始化静态变量存放在.bss
        47: 080494fc     4 OBJECT  GLOBAL DEFAULT   16 a111   # 全局变量为GLOBAL绑定属性  已初始全局变量存放在.data
        48: 0804950c     0 OBJECT  GLOBAL DEFAULT   17 _DYNAMIC
        49: 080484d0     4 OBJECT  GLOBAL DEFAULT   14 _fp_hw
        50: 080494f0     0 NOTYPE  GLOBAL HIDDEN  ABS __fini_array_end
        51: 080494f4     0 OBJECT  GLOBAL HIDDEN   16 __dso_handle
        52: 08048440    66 FUNC    GLOBAL DEFAULT   12 __libc_csu_fini
        53: 08048274     0 FUNC    GLOBAL DEFAULT   10 _init
        54: 0804829c   427 FUNC    GLOBAL DEFAULT  UND malloc@@GLIBC_2.0     55: 080482d0     0 FUNC    GLOBAL DEFAULT   12 _start
        56: 080494f0     0 NOTYPE  GLOBAL HIDDEN  ABS __fini_array_start
        57: 080483f0    71 FUNC    GLOBAL DEFAULT   12 __libc_csu_init
        58: 08049500     4 OBJECT  GLOBAL DEFAULT   16 p111
        59: 08049604     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
        60: 0804838c    89 FUNC    GLOBAL DEFAULT   12 main
        61: 080482ac   251 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC _
        62: 080494f0     0 NOTYPE  GLOBAL HIDDEN  ABS __init_array_end
        63: 080494f0     0 NOTYPE  WEAK   DEFAULT   16 data_start
        64: 080484b4     0 FUNC    GLOBAL DEFAULT   13 _fini
        65: 080494f0     0 NOTYPE  GLOBAL HIDDEN  ABS __preinit_array_end
        66: 08049604     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
        67: 080495e8     0 OBJECT  GLOBAL DEFAULT   21 _GLOBAL_OFFSET_TABLE_
        68: 0804960c     0 NOTYPE  GLOBAL DEFAULT  ABS _end
        69: 080494f0     0 NOTYPE  GLOBAL HIDDEN  ABS __init_array_start
        70: 080484d4     4 OBJECT  GLOBAL DEFAULT   14 _IO_stdin_used
        71: 080494f0     0 NOTYPE  GLOBAL DEFAULT   16 __data_start
        72: 00000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses
        73: 080494f0     0 NOTYPE  GLOBAL HIDDEN  ABS __preinit_array_start
        74: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
        75: 080482bc    48 FUNC    GLOBAL DEFAULT  UND strcpy@@GLIBC_2.0

    文件./aaa加载进内存后,再看看变量的地址以及所在的区:

    [test@redhat]# gdb ./aaa
    GNU gdb 6.1.1
    (gdb) disassemble main
    Dump of assembler code for function main:
    0x0804838c <main+0>:    push   %ebp
    0x0804838d <main+1>:    mov    %esp,%ebp
    0x0804838f <main+3>:    sub    $0x18,%esp
    0x08048392 <main+6>:    and    $0xfffffff0,%esp
    0x08048395 <main+9>:    mov    $0x0,%eax
    0x0804839a <main+14>:   sub    %eax,%esp
    # char s333[] = "abc";
    0x0804839c <main+16>:   mov    0x80484df,%eax            # 0x80484df处为"abc",位于.rodata
    0x080483a1 <main+21>:   mov    %eax,0xfffffff8(%ebp)     # 0xfffffff8(%ebp) 为局部变量 char s333[]
    # char *p333 = "123456";
    0x080483a4 <main+24>:   movl   $0x80484e3,0xfffffff0(%ebp)  # 0x80484e3处为"123456/0",位于.rodata; 0xfffffff0(%ebp) 为局部变量 char *p333
    # p111 = (char *)malloc(10);
    0x080483ab <main+31>:   sub    $0xc,%esp
    0x080483ae <main+34>:   push   $0xa          # 0xa=10 ; push $0xa后,此时堆栈esp值又减去4字节,相当于sub $0x10,%esp
    0x080483b0 <main+36>:   call   0x804829c <malloc>
    0x080483b5 <main+41>:   add    $0x10,%esp
    0x080483b8 <main+44>:   mov    %eax,0x8049500  # 0x8049500 为全局变量p111,位于.data
    # p222 = (char *)malloc(20);
    0x080483bd <main+49>:   sub    $0xc,%esp
    0x080483c0 <main+52>:   push   $0x14        # 0x14=20 ; push $0xa后,此时堆栈esp值又减去4字节,相当于sub $0x10,%esp
    0x080483c2 <main+54>:   call   0x804829c <malloc>
    0x080483c7 <main+59>:   add    $0x10,%esp
    0x080483ca <main+62>:   mov    %eax,0xfffffff4(%ebp)  # 0xfffffff4(%ebp) 为局部变量p222
    # strcpy(p111, "123456");
    0x080483cd <main+65>:   sub    $0x8,%esp
    0x080483d0 <main+68>:   push   $0x80484e3    # 0x80484e3处内容为"123456/0",位于.rodata; 
    0x080483d5 <main+73>:   pushl  0x8049500     # 0x8049500 为全局变量p111,位于.data
    0x080483db <main+79>:   call   0x80482bc <strcpy>
    0x080483e0 <main+84>:   add    $0x10,%esp
    0x080483e3 <main+87>:   leave  
    0x080483e4 <main+88>:   ret    
    0x080483e5 <main+89>:   nop    
    0x080483e6 <main+90>:   nop    
    0x080483e7 <main+91>:   nop    
    0x080483e8 <main+92>:   nop    
    0x080483e9 <main+93>:   nop    
    0x080483ea <main+94>:   nop    
    0x080483eb <main+95>:   nop    
    0x080483ec <main+96>:   nop    
    0x080483ed <main+97>:   nop    
    0x080483ee <main+98>:   nop    
    0x080483ef <main+99>:   nop    
    End of assembler dump.
    (gdb) q
    [test@redhat]#

    2016-9-22 20:55
    张朋艺 pyZhangBIT2010@126.com

    展开全文
  • 本次主要是测试使用互斥锁,锁定非临界区带来的性能消耗。 在我们写代码时,有时候通过逻辑的设计,可以使代码中临界区在80%以上不会同时访问。但是从理论上来说,在极端或者概率很低的情况下它是可能成为临界区的...

    概述

    本次主要是测试使用互斥锁,锁定非临界区带来的性能消耗。

    在我们写代码时,有时候通过逻辑的设计,可以使代码中临界区在80%以上不会同时访问。但是从理论上来说,在极端或者概率很低的情况下它是可能成为临界区的。处于程序的稳定性考虑,同样是需要加锁的。

    但是最近在看disruptor文档[1]时,文献提到:

    即使不是临界资源,只要调用了锁就会大幅度的降低性能。
    而我之前在项目中的代码,总是会考虑逻辑上减少多线程去竞争同一个锁,这难道是在做无用功?

    文中采用的是简单的做5亿次++操作,考虑到其是用Java实现的,因此此处采用C来实现,实践来检验一下结果

     

    如果有资源竞争,肯定会导致性能下降。因此我们主要对比进入“假临界区"的场景。

     

    测试代码:

     

    点击(此处)折叠或打开

    1. #include<stdio.h>
    2. #include<time.h>
    3. #include<sys/time.h>
    4. #include<unistd.h>
    5. #include<string.h>
    6.  
    7. #include<pthread.h>
    8.  
    9.  
    10. unsigned long gtimes = 2 * 1000 * 1000 * 1000;
    11. unsigned long i;
    12.  
    13. struct timeval startTime, endTime;
    14.  
    15. pthread_mutex_t gmutex; //ensure not a stack varible;
    16.  
    17. void start_time()
    18. {
    19.     gettimeofday(&startTime, NULL);
    20. }
    21.  
    22. void end_time()
    23. {
    24.     gettimeofday(&endTime, NULL);
    25. }
    26.  
    27. double spend_time()
    28. {
    29.     return 1000 * (endTime.tv_sec - startTime.tv_sec) +
    30.         (endTime.tv_usec - startTime.tv_usec) / 1000.0f;
    31. }
    32.  
    33. void* test_thread(void* argv)
    34. {
    35.     i = gtimes;
    36.  
    37.     start_time();
    38.     while(i--);
    39.     end_time();
    40.  
    41.     printf(" a thread cost time: %.2f ms\n", spend_time());
    42.  
    43.     return NULL;
    44. }
    45.  
    46. void* test_lockthread(void* argv)
    47. {
    48.     i = gtimes;
    49.     pthread_mutex_init(&gmutex,NULL);
    50.  
    51.     start_time();
    52.  
    53.     pthread_mutex_lock(&gmutex);
    54.     while(i--);
    55.     pthread_mutex_unlock(&gmutex);
    56.  
    57.     end_time();
    58.  
    59.     pthread_mutex_destroy(&gmutex);
    60.     printf(" a thread with a pthread_mutex, cost time: %.2f ms\n", spend_time());
    61.  
    62.     return NULL;
    63. }
    64. int main(int argc, char *argv[])
    65. {
    66.     pthread_t pid;
    67.  
    68.     //pthread_create(&pid, NULL, test_thread, NULL);
    69.     pthread_create(&pid, NULL, test_lockthread, NULL);
    70.  
    71.     pthread_join(pid, NULL);
    72.  
    73.     test_thread(NULL);
    74.     test_lockthread(NULL);
    75.  
    76.     return 0;
    77. }


    测试结果:

      不加锁 加锁 效率对比 绝对值 加锁在不同线程
    1 990.86 1007.29 1.66% 16.43 987.79
    2 996.13 997.04 0.09% 0.91 1001.21
    3 988.47 989.19 0.07% 0.72 982.72
    4 993.6 992.02 -0.16% -1.58 986.94
    5 984.85 984.57 -0.03% -0.28 989.66
    6 991.59 986.75 -0.49% -4.84 992.94
    7 986.68 986.72 0.00% 0.04 983.4
    8 989.16 991.17 0.20% 2.01 987.69
    9 987.22 1001.31 1.43% 14.09 985.03
    10 986.27 984.09 -0.22% -2.18 987.14

     

    从上表可以看出:
    如果两个场景在不同的线程中,没有可比性:两者差值不同。
    再考虑到进程调度。理论上偏差也比较大

    如果是同一个线程中,除了第1和第9组数据,差距都不是很大:
    最大偏差<2ms,偏差率<0.5%.
    多数偏差<1ms,偏差率<0.1%.

    那么另外两组误差在哪里呢?同样是时间片。Linux中时间片是10ms。
    在程序中,两个函数是挨着执行的,如果第一个函数执行完成之后,在执行第二个函数的start_time后时间片到期,此时就会多消耗一个时间片。
    那么我们将后一个函数减去时间片,则基本上可以在接收的范围内——实际上还会有至少两次线程切换

    1 990.86 997.29 0.65% 6.43 987.79
    9 987.22 991.31 0.41% 4.09 985.03

     

    结论:

    C 中的锁即使进入临界区,实际没有发生资源争用,基本上等同于进入非临界区。

    但是性能消耗肯定是有的,应该是锁底层实现的首先自旋的时候会识别出来资源可用!

     

    [1] disruptor原文地址:https://mechanitis.blogspot.jp/2011/07/dissecting-disruptor-why-its-so-fast.html

    http://blog.chinaunix.net/uid-28993794-id-5779757.html

    展开全文
  • 如果您尝试移至最近使用的应用程序,则该程序锁定您的手机并返回主屏幕。 如果您尝试查看通知,它会执行相同的操作。 当然,您可以根据需要将其禁用。 计时器结束后,您将有3分钟的时间查看您的消息并使用其他...
  • Ashampoo UnInstaller 9 是安装、测试以及卸载应用程序的完美方案,...只需将桌面图标拖 UnInstaller 的程序图标上启动卸载程序,或是在程序分类中找到程序进行卸载,还可以在程序首页中点击查看最近卸载的应用程序
  • 即,新版支持库可被旧版易语言或易程序使用,旧版支持库也可被新版易语言或易程序使用(只是不支持静态编译)。  静态编译后的易语言EXE/DLL之间不能再共享譬如窗口、窗口组件等类似资源,对于已经静态连接一个...
  • 最近使用刚体控制移动很多,遇到很多比较琐碎的知识点,在此记录一下 锁定轴向 通过刚体组件的Constraints来进行锁定,一般为position锁定y轴,rotation锁定xz轴 物体随机移动 有时候会发生即使没有控制...
  • 欢迎来到ClassiCube 您将在很长一段时间内享受的基于块的游戏! ... 如果您是Minecraft的狂热粉丝,并且最近访问过 ,您可能会注意Mojang删除了所有指向Minecraft Classic的链接。 这样一来,只
  • NOLOCK 和 ROWLOCK 的使用

    2011-01-28 15:20:00
    最近一年老是受MSSQLSERVER数据库阻塞的困扰,单表记录已突破400万条,除了分库似乎没有别的方法,使用分区存储,数据库又要重新设计,考虑到程序使用较多的就是查询,而查询会受更新与删除的影响,更新与删除...
  • 最近一年老是受MSSQLSERVER数据库阻塞的困扰,单表记录已突破400万条,除了分库似乎没有别的方法,使用分区存储,数据库又要重新设计,考虑到程序使用较多的就是查询,而查询会受更新与删除的影响,更新与删除...
  • 最近一年老是受MSSQLSERVER数据库阻塞的困扰,单表记录已突破400万条,除了分库似乎没有别的方法,使用分区存储,数据库又要重新设计,考虑到程序使用较多的就是查询,而查询会受更新与删除的影响,更新与删除...
  • Fix 后台管理最近7天的订单查看不今天和昨天的订单记录的问题 Fix 下单成功后无法扣减库存的问题 Fix 后台管理修改账号数据校验问题和旧账号信息缓存的问题 Fix 后台管理锁定和删除管理员后仍可以登录的问题 Fix ...
  • MBP TouchBar自定义使用

    2020-10-08 18:54:03
    MBP TouchBar 中英文混合输入的助手 相信大家都有中英文输入法切换的...程序主菜单,里面去找程序。 输入法切换。 抱着试一试的心态,打开偏好设置->键盘->自定功能栏。通过触摸板移动下面,将声音三兄弟
  • 使用memcpy踩出来的坑,值得注意

    千次阅读 2020-04-20 17:05:39
    最近在一个qt项目中,数据传输部分多次使用了memcpy,程序编译没有一个警告或报错,但是一运行起来就不稳定了,有时甚至不能运行起来,有时跑起来能传输几条数据,有时又能接收几十条数据,但最终程序都会异常...
  • 最近新的产品开发中,使用了Tornado和mysql数据库。但在基本框架完成之后,我在开发时候发现了一个很奇怪的现象,我在测试时,发现数据库返回不了结果,于是我在mysql中输入show processlist,发现连接数很高,...
  • 最近有一个需求,因为公司网速比较慢,大的图片上传阿里云盘总是失败、中断,无奈只能先把图片同步局域网服务器,然后在想办法写定时程序,晚上下班的时候同步阿里云盘。 百度找了一下资料,最终锁定samba这款...
  • 直到最近,开发超越2D地图的地理空间应用程序需要一个全面的GIS服务如ArcGIS,诺基亚在这里,或谷歌地图。 虽然这些API是强大的,他们也很昂贵,繁重的学习,并锁定地图开发者一个单一的解决方案。 幸...
  • 最近换了个笔记本电脑,系统从XP SP3变为Win 7,IIS版本也变为7.5。但是原来演示用VS2008来创建Web Service的程序不工作了,在调用Web Service时出现了2个问题。 1. 出现 500.19 Error 。错误提示: 不能在此路径...
  • subversion (windows开发)使用后感受

    千次阅读 2006-02-22 10:46:00
    由于VSS(Visual Source Safe,微软提供的一个版本管理工具)实在是bug太多,而且公司有大陆和台湾共同开发程序的需求,最近一段时间项目组开始试用大名鼎鼎的subversion。 我们装的是Windows版本,在客户端安装了...
  • 在所输入的最近区间求z=(x,y)的回归)求大佬教如何使用 ``` #include #include"math.h" #include #include void FreeData(double **dat, double *d, int count) { int i, j; free(d); for(i = 0;i ...
  • 千里马酒店前台管理系统V7使用手册

    热门讨论 2011-06-16 14:09:38
    千里马酒店前台管理系统V7.2具有先进的理念、严谨的设计、全面的功能、优异的性能、非常的稳定、友好的界面、快捷的操作等等特色,从以下软件的功能和使用说明中,您将深切体会这些特色为您带来的好处。...
  • Windows 7 旗舰版高效办公 - 任务栏和 开始 菜单属性 1. 开始 -> 右键 属性 2. 任务栏和 开始 菜单属性 ...3. 自定义 开始 菜单 ...要显示的最近打开过的程序的数目:16 ...7. 将此程序锁定到任务栏 ...
  • 安装了防火墙(包括WINXP系统自带的防火墙),出现无法Ping通,或者是访问共享资源的时候提示"XXX无法访问"、"您可能没有权限使用网络资源"、"请与这台服务器的管理员联系以查明您是否有访问权限"、"找不网络路径...
  • 最近有机会帮助开发人员使用ASP.NETCore应用程序,该应用程序在功能上正确但在用户负载很重时很慢。我们发现了几个不同的因素,这些因素在调查时会导致应用程序的减速,但大部分问题都是阻塞线程的一些变化,这些...
  • Chrome OS专用键盘 Chrome操作系统的其他键盘布局和输入法的集合。 每个目录都是其自己的Chrome扩展程序。... Ctrl +空格键可在最近使用的键盘语言之间切换。 已知局限性 在登录/锁定屏幕上不允许使用这些扩展名。

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 141
精华内容 56
关键字:

锁定到最近使用程序