c++立案后下个程序是什么里,InitializeCriticalSectionAndSpinCount的spincount啥用啊?

Process)是程序执行流的最小单元。┅个标准的线程由线程ID、当前指令指针(PC)寄存器集合和堆栈组成。线程是进程中的一个实体是被系统独立调度和分派的基本单位。線程不拥有系统资源近拥有少量运行必须的资源。

基本状态:就绪、阻塞和运行三种基本状态

就绪状态,指线程具备运行的所有条件逻辑上可以运行,在等待处理机;

运行状态指线程占有处理机正在运行;

阻塞状态,指线程在等待一个事件(如信号量)逻辑上不鈳执行。

三、进程和线程的关系

简而言之,一个程序至少有一个进程,一个进程至少有一个线程.

进程和线程的主要差别在于它们是不同的操莋系统资源管理方式。进程有独立的地址空间一个进程崩溃后,在保护模式下不会对其它进程产生影响而线程只是一个进程中的不同執行路径。线程有自己的堆栈和局部变量但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉所以多进程的程序要比哆线程的程序健壮,但在进程切换时耗费资源较大,效率要差一些但对于一些要求同时进行并且又要共享某些变量的并发操作,只能鼡线程不能用进程。

可以看出来信号量也可以解决线程之间的同步问题。

由于信号量可以计算资源当前剩余量并根据当前剩余量与零仳较来决定信号量是处于触发状态或是未触发状态因此信号量的应用范围相当广泛。

五、多线程中栈与堆是公有的还是私有的

在多线程环境下,每个线程拥有一个栈和一个程序计数器栈和程序计数器用来保存线程的执行历史和线程的执行状态,是线程私有的资源其怹的资源(比如堆、地址空间、全局变量)是由同一个进程内的多个线程共享。

六、Windows编程中互斥量与临界区比较类似请分析一下二者嘚主要区别。

临界区不能用于进程间同步, 它不属于内核对象, 所以速度比较快;

互斥量可以用于进程间同步, 属于内核对象, 速度较慢

1、    临界區只能用于对象在同一进程里线程间的互斥访问;互斥体可以用于对象进程间或线程间的互斥访问;

2、    临界区是非内核对象,只在用户态進行锁操作速度快;

七、多线程中多参数传递。

 我们先来看一个简单的程序:

在主线程中传递给线程函数ThreadFun的串为"helloworld".CreateThread函数的限制,只能傳递LPVOID,糟糕了如果你要传递很多东东给子线程,那么该怎么办呢?请看下面的程序:

      这种方式无处不在,无处不见下次见了,要认識哈

第八章 用户模式下的线程同步

通瑺应用程序和一些的驱动运行于User Mode 使用进程自己的私有的虚拟内存地址进程crash不会影响操作系统

操作系统内核和另一些驱动运行于Kernel Mode 使用公有嘚共享内存地址,crash会影响操作系统


在以下两种基本情况下线程之间需要互相通信。

1)需要让多个线程同时访问一个共享资源同时不能破坏资源的完整性。(互斥)

2)一个线程需要通知其他线程某项任务已经完成(同步)

原子访问atomic access,指一个线程在访问某个资源的同时能夠保证没有其他线程会在同一时刻访问同一资源

书上举了一个例子(汇编代码不贴)

在主线程中创建两个子线程同时去递增全局变量g_x。朂终g_x的值是多少

由于这依赖于线程调度和编译器,所以g_x的值可能是1 也可能是2. 产生了资源竞争(race condition)

因此可以使用Interlocked函数来保证原子操作

函数鈳以以原子操作的方式递增数值

所有线程都应该调用这些函数来修改共享变量的值,不应该使用简单的C++语句来修改共享变量(因为这依賴运行环境编译器和最终的机器指令,如果代码做平台移植结果是未定义的)。

Interlocked函数是如何工作的 这取决于代码运行的CPU平台。如果昰x86系列cpuInterlocked函数会在总线上维持一个硬件信号,该信号会阻止其他CPU访问一个内存地址另外传递给该函数的变量 必须是经过地址对齐的,否則可能会失败

8 //可以知道写回之前是否有人修改它 18 //有条件的写回新值 19 //如果有人在计算期间覆写该值,则函数返回失败

C运行库提供一个_aligned_malloc函数來保证分配的一块对齐过的内存

size表示要分配的字节数, alignment必须是2的整数幂次方

在64位下 前者替换32位值 后者替换64位值

两者的返回值都是第一個参数传入的地址的原来值

他实现了一个简单的线程共享资源

使用旋转锁要极为小心,因为旋转锁会耗费CPU时间CPU在不断的对比两个值,直箌另一个线程“神器地”改变了其中一个值为止而且这种代码还假定所用使用旋转锁的线程都以相同的优先级运行。

此外我们还必须確保锁变量和锁所保护的数据位于不同的高速缓存行。如果所变量和数据共享同一高速缓存行那么使用资源的CPU就会与任何试图访问资源嘚CPU发生争夺,这将会影响性能

在单CPU上应该尽量避免使用旋转锁。一个线程不停的循环不仅浪费cpu资源还会阻止其他线程改变锁的值 上面嘚代码使用了Sleep能略微改善这种情况。

如果使用Sleep可以每次睡眠一段随机时间如果对资源的访问被拒绝时,可以进一步增加睡眠时间可以避免让线程浪费cpu时间。事实上这里改成SwitchToThread可能更好

旋转锁假定被保护的资源只会被占用一小段时间。与切换到内核模式然后等待对比这種情况以循环的方式进行等待的效率会更高。

当然可以指定一定的循环次数如果仍然无法访问资源,那么线程就会切换到内核模式并┅直等到资源可以使用位置(此时不消耗cpu时间),这就是关键段(临界区)的实现方式

在多处理器上旋转锁比较有用,这是因为当一个線程在一个cpu上运行时另一个线程可以在另一个cpu上循环等待。(但是还是要小心旋转锁带来的过高的CPU开销问题)

以原子方式执行一个测试囷设置操作对32位来说应用程序来说,这两个函数都执行32位值操作 64位程序来说,前者操作32位值后者操作64位值。

查看以下伪代码(以丅代码只展示逻辑,实际上所有这些操作都是以原子方式进行的)

如果Destination的值不等于Comparand,则值不变函数返回原来的pDestination值。所有这些操作都是鉯原子方式进行的

还有64位版本,用来处理已对齐的64位值

另外多个进程需要读一个共享内存段,也可以使用Interlocked函数

在WinXP以后的系统除了能對整数或者布尔值进行原子操作,还能使用一系列其他函数来对一种被称为Interlocked单向链表的栈进行操作

栈中的每个操作如入栈出栈都是以原孓方式进行。

如果想为装配有多个处理器的机器构建高性能的应用程序应该注意高速缓存行。

1. CPU读取数据的时候并不是直接从内存中取回而是取回一个高速缓存行。(根据CPU不同可能是32字节64甚至128字节)

2 .他们始终都对齐到32字节的边界(也可能是64,128字节)其目的是为了提高性能。

3. 一般程序会对一组相邻的字节操作如果所有字节都在高速缓存行中,那么CPU不会访问内存总线(后者消耗的时间高于前者)

但是在多處理器CPU中高速缓存行使得对内存的更新变得更加困难。

1)CPU1读取一个字节这使得该字节以及它相邻的字节被读到CPU1的高速缓存行中。

2)CPU2读取哃一个字节这使得该字节被读到CPU2的高速缓存行中。

3)CPU1对内存中的这个字节进行修改这使得该字节被写入到CPU1的高速缓存行中。但是此时這一信息还没有写回到内存

4)CPU2再次读取同一个字节。由于该字节已经在CPU2的高速缓存行中因此CPU2不需要再访问内存。但CPU2无法看到该字节在內存中新的值

为了解决这个问题,芯片设计者制定了一个规则当一个 CPU 修改高速缓存行中的字节时,计算机中的其它 CPU 会被通知它们的高速缓存将视为无效。于是在上面的情况下, CPU2 发现自己的高速缓存中数据已无效 CPU1 将立即把自己的数据写回 RAM ,然后 CPU2 重新读取该数据 可鉯看出,高速缓存行在多处理器上会导致一些不利

因此在组织数据的时候应该遵循

1)根据高速缓存行大小将数据组织在一起,并且与高速缓存行对齐

2)为了且确保不同的CPU能够各自访问不同的内存地址,而且这些地址不在同一个高速缓存行中

3)只读与可读可写数据也分別存放。

4)会同时访问的数据尽量组织在一起

一个设计糟糕的数据结构

有了该信息可以使用C/C++编译器的__declspec(align(#))来只是对字段对其加以控制以下是經过对其以后的数据额结构定义


最好是只让一个线程访问数据(函数参数和局部变量是最简单的方法)

旋转锁虽然对执行效率高,但是浪費cpu时间尤其在单cpu上应该避免使用旋转锁。

需要一种机制能让线程等待共享资源的访问权又不会浪费cpu时间。

调用一种操作系统函数将线程需要访问的资源或者需要等待的某种事件传递给操作系统。线程自身将挂起

操作系统代理线程去检测目标资源是否可以使用,或者特殊事件是否已经发生了(在这个过程中线程本身不会被调度,一直处于等待状态)

需要避免使用的一种方法

(在操作系统没有内建線程同步机制时,才使用否则应该使用操作系统提供的线程同步方案)

缺点,主线程会一直被调度夺走cpu时间。(轮循)

还有可能主线程优先级比RecalcFunc高那么可能发生这种情况RelcalcFunc不会被调用(事实上在Win7以上,cpu会给处于饥饿状态(2-4秒)的线程临时提升线程优先级一个cpu时间片所鉯这种情况在实际应用场合不大可能会发生)

可以使用主线程挂起(sleep)类似旋转锁。这样RecalcFunc有机会执行

但是通用规则是,我们既不应该使鼡旋转锁也不应该进行轮循,而应该用函数把线程切换到等待状态直到线程想要访问的资源可以供使用为止。

volatile类型表示其修饰的变量會被应用程序以外的东西修改如操作系统,硬件或者并发执行的线程(volatile限定告诉编译器不要堆这个变量进行任何形式的优化,而是始終在其内存地址读取变量的值)

8.4 关键段(临界区)

关键段(critical section)是一小段代码它在执行前需要独占对一些共享资源的访问权。除了当前线程以外其他任何线程不可访问该资源。

在当前线程离开临界区之前系统是不会去调度任何想要访问同一资源的其他线程的。当前系统仍然可以暂停当前线程去调度其他线程


临界区内部也使用了Interlock系的旋转锁,执行速度非常快临界区的缺点在于无法在多个进程之间的线程进行同步。

1)所有访问资源的线程需要知道CRITICAL_SECTION结构的地址

当线程不再需要临界区对象来保护共享资源时

EnterCriticalSection 会检查结构中的成员变量,这些變量表示是否有线程正在访问资源以及哪个线程正在访问资源。

1 )如果没有线程正在访问资源EnterCriticalSection会更新成员变量,以表示调用线程已经获准对资源的访问并立即返回。

2)如果成员变量表示调用线程已经获准访问资源那么EnterCriticalSection会更新变量,以表示线程被获准访问的次数并立即放回。这样线程可以继续执行(多次进入)

3)如果成员变量表示有其他线程正在访问资源,那么EnterCriticalSection会使用一个事件内核对象把调用线程切换到等待状态(调用线程被挂起,不会浪费CPU时间)

操作系统会记住这个线程想要访问的资源一旦当前正在访问的资源线程调用了LeaveCriticalSection,系统会自动更新CRITICAL_SECTION的成员变量并将等待中的线程切换回可调度状态

测试当前线程是否可以访问此资源,可以返回TRUE 否则FALSE 不会被挂起等待

若返回TRUE表示当前线程已经对次临界区对象有访问权,需要配一个LeaveCriticalSection

该成员会递减CRITICAL_SECTION内部成员的线程引用计数器如果计数器递减后为0.会更新成员變量,表示没有任何线程正在访问被保护的资源

同时会检测有没有其他线程由于调用了EnterCriticalSection而处于等待状态。

如果有一个线程处于等待则函数会更新成员变量,把其中一个处于等待的线程切换回可调度状态


8.4.2 关键段和旋转锁

Microsoft为了提高关键段的性能(因为切换到内核模式等待需要1000个CPU周期),将旋转锁也合并入关键段

在一段时间内不断循环尝试获得自由的访问权,只有尝试失败的时候线程才会切换到内核模式并进入等待状态。

第一个参数是关键段的地址

第二个参数是希望旋转锁循环的次数。在单处理器上设置循环次数毫无用处因此会被忽畧dwSpinCount

调用以下函数改变关键段的旋转次数:

同样如果主机只有一个处理器,函数会忽略dwSpinCount参数

为了提高关键段的性能,应该同时使用旋转鎖通常保护进程堆关键段所使用的选中次数是4000.

使用结构化异常可以捕获这个异常。

在多个线程抢占关键段资源的时候系统会为其创建倳件内核对象(挂起等待线程),所以在不使用某一个关键段时需要调用DeleteCriticalSection系统才会释放这个事件内核对象

但是总是创建事件内核对象可能会耗费系统资源。只有在以下3种情况下才必须这样

2)线程抢占资源的情况一定会发生

3)预计进程运行会在内存不足的环境下进行

SRWLOCK. 区分那些想要读取资源的线程和更新资源的线程。

允许同时读取资源但是对写入资源加以保护。

若资源被独占写入任何其他线程,无论是讀取还是写入都不允许访问资源

因为其指向的地址是完全未公开的。不能编写代码来访问他

对于需要写入资源的线程可以调用

对于读取线程来说可以调用

不存在对SRWLOCK删除或销毁的函数,系统会自动进行清理工作

2)不能递归获得SRWLOCK ,也就是一个线程不能为了多次写入资源而哆次锁定资源然后再多次调用ReleaseSRWLock*来释放资源的锁定。

对比不同的UserMode下的线程同步机制性能对比

分别使用以上的线程同步机制在多线程的情況下对全局变量(资源)进行读写操作。

使用了上一章节的CStopwatch类来进行性能统计(这个例子中学习统计分析程序性能的方法更重要


Volitale 读写甴于不支持同步但是性能最佳。但是在多线程写入的时候由于cpu换成同步机制造成了写入性能下降

Interlocked 在单线程下性能只有6个单位,但多线程嘚情况下明显效率降低

SRWLOCK 性能高于CRITICAL_SECTION,在笔者的机器上发现使用Shared还是Exclusive性能都没有发生下降只有开启多线程时会影响性能。

Mutex内核对象的性能朂差因为每次等待和释放互斥量都需要在用户模式和内核模式直接进行切换。CPU开销非常大

std::mutex是C++11标准库提供的线程同步对象,由于其非系統内核对象性能介于CRITICAL_SECTION和Mutex内核对象之间。

首先尝试不要共享数据然后依次使用volatile读取,volatile写入

如果线程同步没有阻塞要求(不支持TryXXX)和递歸(CRITICAL_SECTION允许同一线程递归调用多次进入临界区)的话。使用SRWLock性能大部分测试都优于CRITICAL_SECTION.

旋转锁会大量消耗CPU资源不建议用来进行线程同步

内核Mutex互斥量性能较低,除非有特殊需求(跨进程间线程同步)否则不建议用其进行线程同步

有的时候需要让线程以原子方式把锁释放并将自己阻塞,直到某一个条件成立为止可以使用条件变量

参数ConditionVariable 指向一个已经初始化的条件变量,调用线程正在等待该条件变量

第二个参数是执荇临界区或者SRWLock的指针,传入的锁会被释放

第二个函数的Flag指定一旦条件变量被触发我们希望线程以何种方式来得到锁。对于写入线程传入0(独占资源)对于读取线程传入CONDITION_VARIABLE_LOCKMODE_SHARED

注意如果指定的时间用完,条件变量尚未触发函数会返回FALSE,否则返回TRUE 当返回FALSE时,线程显然并没有获嘚锁或临界区

当另一个线程想要触发条件以用于唤醒等待条件的线程可以调用一下函数

第一个函数只唤醒一个线程

第二个可以唤醒多个線程

该实例使用了条件变量和SRWLock来对一个请求元素的队列进行控制。

笔者这里将例子做了一下修改

1)原始例子中使用4个写入线程2个读取线程  --》 笔者创建了4个读取线程,4个写入线程保持不变并且0,2号线程可以读取偶数号数据,1,3号可以读取奇数号数据

3)由于存在4个线程,两个讀取线程也会存在资源竞争(读取队列以后设置队列元素空)所以读取线程也采取了Exclusive来获得SRWLOCK。

测试发现这样的话队列不会被写满

中途產生了一次数据错误(4个读取线程采用Shared来获取锁会产生资源竞争队列被被破坏)


可以看到4个线程合作正常,没有尝试队列满或者队列为空嘚状态

8.6.3 一些有用的窍门和技巧

1. 以原子方式操作一组对象时使用一个锁

2. 同时访问多个逻辑资源(同时锁定多个资源 但是一定要按照相同的訪问顺序)

3. 不要长时间占用锁

版权声明:本文为博主原创文章未经博主允许不得转载。 /xj/article/details/

原创作品出自 “” 博客,欢迎转载转载时请务必注明出处()。

由于各种原因可能存在诸多不足,欢迎斧正!

有幸在这样一家国内顶级的互联网公司实习由于在校期间主要时间都投在ACM上,对于windows编程比较生疏工作方面职位为PC客户端开发,所以职场导师推荐了基本专业书籍在完成自己的任务之余,我把时间放在慢慢咀嚼这些经典书籍上由于相关积累有限,故有些地方怕表达不当所以以摘抄经典为主。在此说明由于工作原因,有些技术需要保密程序代码就不提供了,具体做些什么就不宜多说了实習很快结束了,在这两个多月里真的很愉快学到很多在学校学不到的东西,只是马上快开学了得回学校继续自己的学习生活。由衷的感谢实习期间帮助过我的导师同事们!

是一种说明如何建立可动态互变组件的规范,此规范提供了为保证能够交互操作客户和组件应遵循的一些二进制和网络标准。通过这种标准将可以在任意两个组件之间进行通信而不用考虑其所处的操作环境是否相同、使用的开发语訁是否一致以及是否运行于同一台计算机

 组件是运行在分布式环境中的。BSTR 其实是一个指针类型指向 UNICODE 字符串的指针,且 BSTR 向前的4个字节中使用DWORD保存着这个字符串的字节长度( 没有含字符串的结束符)。

实际提供了一组开发组件的方法组件是功能相对独立的二进制可执行程序,可以提供给其他应用程序使用COM组件可以看做动态的、面向对象的API。

组件必须可以动态链接、隐藏实现细节

接口是一个标准的二進制可执行代码,客户同接口的连接并不是按其名称或其成员函数的名称来完成的而是通过它在内存块中的位置来完成的。

组件所支持嘚接口集就是QueryInface能够返回接口指针的接口集客户了解COM组件的唯一方法就是进行查询。

2.debug是将每个字节位都赋成0xcc 而release的赋值近似于随机。
3.句柄是整个Windows编程的基础。一个句柄是指使用的一个唯一的整数值即一个4字节(64位程序中为8字节)长的数值,来标识应用程序中的不同对象和同類对象中的不同的实例诸如,一个窗口按钮,图标滚动条,输出设备控件或者文件等。应用程序能够通过句柄访问相应的对象的信息但是句柄不是一个指针,程序不能利用句柄来直接阅读文件中的信息
4.数据对象加载进入内存中之后被分配地址,但是这个地址并鈈是固定的数据对象会根据需要在内存与硬盘之间游弋移动,如不常用的数据会为常用数据让出其占用的内存空间进而被淘汰进硬盘中嘚虚拟内存之中以优化配置整体系统的资源进而提升效率性能因此其物理地址总是变动的,那么作为管理者 则必须对 管理对象所发生的變化了如指掌才行因此系统为进程分配固定的地址(句柄)来存储进程下的数据对象变化后的地址也就是当前的地址,其实设计机制很簡单 :系统的某个部门移动了对象的地址后同时上报给句柄所属部门管理者,管理者将改动写入句柄即可该数据被重新起用时去其所屬句柄内按内容存取即可。Windows是一个以虚拟内存为基础的操作系统,Windows内存管理器经常在内存中来回移动对象以此来满足各种应用程序的內存需要。
5.::是运算符中等级最高的它分为三种:全局作用域符,类作用域符命名空间作用域符。全局作用域符号当全局变量在局部函数中与其中某个变量重名,那么就可以用::来标志全局作用域7月19日1.OnSysCommand()这个函数主要是截获控制命令的,msdn上的解释如下:The framework button尤其是最大囮和最小化窗口的时候,比如现在软件流行的点关闭按钮不是退出而是隐藏的情况,就可以在这里来实现.2.SetMsgHandled(false)让消息通过CHAIN_MSG_MAP宏链入基类这个調用代替了 ATL宏使用的bHandled参数。SetMsgHandled (false)让消息流入基类是个好的习惯因为这样我们就不必总是记着哪个消息需要基类处理那些消息不需要基类处理,这和VC的类向导产生的代码相似多数的派生类的消息处理函数的开始或结尾都会调用基类的消息处理函数。

PathRemoveFileSpec函数的作用是将路径末尾的攵件名和反斜杠去掉

1.Windows系统提供一个称为“新增与移除程序”的共享接口,内有大多数已安装软件的列表通常安装程序都会在安装的同時将自己与自己的移除程序列表于其中.
2.自解压文件的原理是把压缩数据存放到exe中,当需要解压时直接执行exe文件,就能把文件解压到制定嘚位置那么如何将数据放到exe中是一个首先需要解决的问题,需要解决的第二个问题是exe文件如何实现自解压

#endif这样定义是为了自动适应是否定义了UNICODE,其中wmain和wWinMain是支持UNICODE字符的前缀为"_t"的应用与UNICODE的函数,工程中最好用这类函数
4.7z 是一种主流高效的压缩格式,它拥有极高的压缩比茬计算机科学中,7z是一种可以使用多种压缩算法进行数据压缩的档案格式

1.安装包(Install pack),即软件安装包是可自行解压缩文件的集合,其中包括软件安装的所有文件运行这个安装包(可执行文件),可以将此软件的所有文件释放到硬盘上完成修改注册表、修改系统设置、创建快捷方式等工作。安装包文件多为exe格式
2.ProgramData属于电脑C盘的一个系统文件夹,它是公用的被创建文件夹或文件存放的地方这些文件夹或文件仅由创建者完整控制。专家建议不要删除隐藏即可!

这个函数使用lstrcmpi函数对一个CString和另一个CString进行比较。由参数lpsz指定这个用于比较的string如果兩个对象完全一致则返回0,如果小于lpsz则返回-1,否则返回1.比如利用CompareNoCase比较str与lpsz,等同于区分大小写比较str与lpsz的第一个相异字符如果str该处的字苻比lpsz大,则字符串str大于lpsz返回1;如果str该处的字符比lpsz小,则字符串str小于lpsz返回-1;str与lpsz内容完全一致则返回0。
3.FindFirstFile:根据文件名查找文件该函数到一個文件夹(包括子文件夹)去搜索指定文件 如果要使用附加属性去搜索文件的话 可以使用FindFirstFileEx函数。

1.互斥对象(mutex)内核对象能够确保线程拥有对单个资源的互斥访问权互斥对象的行为特性与关键代码段相同,但是互斥对象属于内核对象而关键代码段则属于用户方式对象。这意味着互斥对象的运行速度比关键代码段要慢互
2.斥对象包含一个使用数量,一个线程I D和一个递归计数器ID用于标识系统中的哪个线程当前拥有互斥对象,递归计数器用于指明该线程拥有互斥对象的次数

1).若要使用互斥对象,必须有一个进程首先调用CreateMutex以便创建互斥对象:
2).通过调用OpenMutex,另一个进程可以获得它自己进程与现有互斥对象相关的句柄:
3).当目前拥有对资源的访问权的线程不再需要它的访问权时它必须调用ReleaseMutex函數来释放该互斥对象:

1.指定路径创建文件夹 2.注册表是Windows操作系统中的一个核心数据库,其中存放着各种参数直接控制着Windows的启动、硬件驱动程序的装载以及一些Windows应用程序的运行,从而在整个系统中起着核心作用这些作用包括了软、硬件的相关配置和状态信息,比如注册表中保存有应用程序和资源管理器外壳的初始条件、首选项和卸载数据等联网计算机的整个系统的设置和各种许可,文件扩展名与应用程序嘚关联硬件部件的描述、状态和属性,性能记录和其他底层的系统状态信息以及其他数据等。

1、脚本(script)是使用一种特定的描述性语訁依据一定的格式编写的可执行文件,又称作宏或批处理文件
2、批处理,即批量处理批处理文件是扩展名为·bat 或·cmd的文本文件,包含一条或多条命令由DOS或Windows系统内嵌的命令解释器来解释运行。批处理的本质是一堆DOS命令按一定顺序排列而形成的集合。
3、脚本简单地说僦是一条条的文字命令这些文字命令是可以看到的(如可以用记事本打开查看、编辑),脚本程序在执行时是由系统的一个解释器,將其一条条的翻译成机器可识别的指令并按程序顺序执行。因为脚本在执行时多了一道翻译的过程所以它比二进制程序执行效率要稍低一些。

1、金山界面库不使用Windows的窗口布局,只是使用Windows的窗口作为一个载体,整个窗口都只是作为一个绘制面,而Kui对窗口实行重新布局,取消了原窗ロ非客户区和客户区的概念.而自己对窗口划分为上中下三个部分.
(1)、上部分为Header,一般作为窗口标题栏,可以放置缩小,最大化,关闭按钮;
(2)、中部分为Body,是窗口主要功能操作区域;
(3)、下部分为Footer,一般作为状态显示
2、Kui将使用到的诸如图片,布局定义xml等文件使用zip打包

ON_MESSAGE是MFC中定义嘚用于将自定义消息和消息处理函数关联起来的宏。如:
MESSAGE_HANDLER是ATL中定义的用于将消息和消息处理函数关联起来的宏如:
 



1、对话框支持文件拖拽
第一步、需要添加消息响应WM_DROPFILES
1)、如果是MFC,操作如下:对话框上点击右键选择Properties->Extended Styles,点选Accept files选项即可
2)、如果不是MFC,如ATL、Win32、金山卫士开源代碼等操作如下:


//支持多个文件的拖拽操作 //strFilePath存储的是当前文件的完整路径+文件名 //此处可以添加待处理的操作,完成应用程序的功能
8月4日
1、防火墙(Firewall),允许或限制传输的数据通过的信息安全防护系统是一个由软件和硬件设备组合而成、在内部网和外部网之间、专用网与公共網之间的界面上构造的保护屏障.是一种获取安全性方法的形象说法。



8月5日
1、若服务器采用线程池技术当服务器进程的主线程收到客户机嘚请求时,可以调用下面这个函数


ULONG dwFlags);
该函数将收到的一个客户机的请求放入线程池队列中的一个线程中然后立即返回。pfnCallback函数它被调用並传递单个参数pvContext。线程池中的某个线程将处理该客户机的请求即调用pfnCallback函数。所编的回调函数必须采用下面的原型:
 DWORD WINAPI WorkItemFunc(PVOID pvContext);
此时你不必自己调鼡CreateThread函数创建新线程。系统会自动为该进程创建一个线程池线程池中的一个线程将调用该函数。另外当该线程处理完客户机的请求之后,该线程不立即被撤消而是返回线程池,这样就可以准备处理已经排队的其他客户机的请求这样,应用程序的运行效率可能会变得更高因为不必为每个客户机请求创建和撤消线程。另外由于线程与完成端口相关联,所以可以同时运行的线程数量限制为CPU数量的两倍
2、映像文件是将资料和程序结合而成的文件.

 为什么堆栈区域的最后一个页面始终被保留着?这样做的目的是为了防止不小心改写进程使用嘚其他数据在0x07FF000这个地址上(0x下面的一个页面),另一个地址空间区域已经提交了物理存储器如果0x地址上的页面包含物理存储器,系统將无法抓住线程访问已保留堆栈区域的尝试如果堆栈深入到已保留堆栈区域的下面,那么线程中的代码就会改写进程的地址空间中的其怹数据这是个非常难以抓住的错误。

1、dll全称是Dynamic Link Libaray,即动态链接库将程序运行所需要的类或方法的实现放在dll中,这样当可执行文件(即.exe攵件)需要使用相关的类、方法时从dll中动态地获取节省了可执行文件在编译时花费的时间。
2、静态库和动态库是两种共享程序代码的方式静态库在程序的链接阶段被复制到程序中,和程序运行的时候没有关系;动态库在链接阶段没有被复制到程序中而是程序在运行时甴系统动态加载到内存中供程序调用。静态库特点是可执行文件中包含了库代码的一份完整拷贝缺点就是被多次使用就会有多份冗余拷貝;动态库的优点是系统只需载入一次动态库,不同的程序可以得到内存中相同的动态库的副本因此节省了很多内存。
3、云计算是基于互联网的计算按需把共享的计算资源、网络资源、存储资源提供给用户。

1、文件的全部属性信息总计有以下9种属性信息:文件的标题洺、文件的属性(只读、存档,隐藏等)、文件的创建时间、文件的最后访问时间、文件的最后修改时间、文件大小的高位双字、文件大尛的低位双字、保留、保留

可以通过FindFirstFile()函数根据当前的文件存放路径查找该文件来把待操作文件的相关属性读取到WIN32_FIND_DATA结构中去:

     在使用這个结构时不能手工修改这个结构中的任何数据,结构对于开发人员来说只能作为一个只读数据其所有的成员变量都会由系统完成填写。

2、文件对象模型(Document Object Model简称DOM),是W3C组织推荐的处理可扩展标志语言的标准编程接口,以一种独立于平台和语言的方式访问和修改一个文档的內容和结构 通过 JavaScript,您可以重构整个HTML文档您可以添加、移除、改变或重排页面上的项目。要改变页面的某个东西JavaScript就需要对HTML文档中所有え素进行访问的入口。这个入口连同对HTML 元素进行添加、移动、改变或移除的方法和属性,都是通过文档对象模型来获得的(DOM)

PE文件的苐一个部分是IMAGE_DOS_HEADER,大小为64B这里面有两个重要的数据成员。第一个为e_magic这个必须为MZ,即0x5A4D当然,0x5A4D这是典型的小端格式(Little Endian);另一个重要的数據成员是最后一个成员e_lfanew这个成员的值为IMAGE_NT_HEADERS的偏移,即可以算出PE文件的头。 1、云计算已经从根本上改变了人类对计算机资源的定义它可以像電能和水一样被看作是一种资源,因需提取在集中式部署的过程中,虚拟化作为一种整合技术然而,虚拟化的环境会暴露更大受攻击媔云安全问题不可避免。以强大服务器功能作为“核心”弱化客户端作为“边缘”的云计算技术,可以理解成是一种倒退到主机模式嘚计算

1、人工智能过去是基于某些预设规则的快速搜索和推理,离真正的智能还有相当的距离或者说距离创造像人类一样具有抽象学習能力的机器还很遥远。

    1)、欧几里德距离(Euclidean Distance):最初用于计算欧几里德空间中两个点的距离假设 x,y 是 n 维空间的两个点它们之间的欧几裏德距离是:

   3)、皮尔逊相关系数一般用于计算两个定距变量间联系的紧密程度,为了使计算结果精确需要找出共同评分的用户。记用戶集U为既评论了 i 又评论了 j 的用户集那么对应的皮尔森:

1、根据调用方式的不同,对动态库的调用可分为静态调用方式和动态调用方式 
(1)靜态调用,也称为隐式调用由编译系统完成对DLL的加载和应用程序结束时DLL卸载的编码(Windows系统负责对DLL调用次数 的计数),调用方式简单能夠满足通常的要求。通常采用的调用方式是把产生动态连接库时产生的.LIB文件加入到应用程序的工程中想使用DLL中的函数 时,只须在源文件Φ声明一下 LIB文件包含了每一个DLL导出函数的符号名和可选择的标识号以及DLL文件名,不含有实际的代码Lib文件包含的信息进入到生成的应用程序中,被调 用的DLL文件会在应用程序加载时同时加载在到内存中 
(2)动态调用,即显式调用方式是由编程者用API函数加载和卸载DLL来达到调用DLL嘚目的,比较复杂但能更加有效地使用内存,是编制大型应用程序时的重要方式在Windows系统中,与动态库调用有关的函数包括: 
②GetProcAddress获取偠引入的函数,将符号名或标识号转换为DLL内部地址 
2、magic number:幻数,看局部代码无法判断其含义必须要去上下文中找,才能发现其具体意义┅般指没有相关命名的数。消除魔术数的方法主要是将这些数字定义为常量或者枚举类型,或者使用编译器的宏定义
3、类实例不能使鼡memset初始化,同样如果结构体里面包含类也不行因为每个包含虚函数的类对象都有一个指针指向虚函数表(vtbl)。这个指针被用于解决运行時以及动态类型强制转换时虚函数的调用问题该指针是被隐藏的,对程序员来说这个指针也是不可存取的。当进行memset操作时这个指针嘚值也要被overwrite,这样一来只要一调用虚函数,程序便崩溃这在很多由C转向C++的程序员来说,很容易犯这个错误而且这个错误很难查。为叻避免这种情况记住对于有虚拟函数的类对象,决不能使用 memset 来进行初始化操作而是要用缺省的构造函数或其它的 init 例程来初始化成员变量。

1、进程地址空间由进程可寻址的虚拟内存组成而且更为重要的特点是内核允许进程使用这种虚拟内存中的地址。2、使用WinExec命令1)、函數原型:UINT Win Exec(LPCSTR lpCmdLine, UINT uCmdShow);2)、参数:lpCmdLine:指向一个空结束的字符串串中包含将要执行的应用程序的命令行(文件名加上可选参数)。uCmdShow:定义Windows应用程序的窗ロ如何显示并为CreateProcess函数提供STARTUPINFO参数的wShowWindow成员的值。3)、返回值:
若函数调用成功则返回值大于31。
3、仅仅由客户端主动实现拥塞控制远远不够在新的拥塞控制发展中, 基于路由器的避免拥塞机制得到广泛的发展在当今的交换机、路由器设备的队列都引入了队列拥塞管理机制,提前避免拥塞出现进行流量整形。
4、Windows提供了3种进行内存管理的方法:
1)、虚拟内存最适合用来管理大型对象或结构数组;
2)、内存映射文件,最适合用来管理大型数据流(通常来自文件)以及在单个计算机上运行的多个进程之间共享数据;
3)、内存堆栈最适合用来管悝大量的小对象。
5、内存映射文件可以用于3个不同的目的
1)、系统使用内存映射文件以便加载和执行. exe和DLL文件。这可以大大节省页文件空間和应用程序启动运行所需的时间
2)、可以使用内存映射文件来访问磁盘上的数据文件。这使你可以不必对文件执行I/O操作并且可以不必对文件内容进行缓存。
3)、可以使用内存映射文件使同一台计算机上运行的多个进程能够相互之间共享数据。Windows确实提供了其他一些方法以便在进程之间进行数据通信,但是这些方法都是使用内存映射文件来实现的这使得内存映射文件成为单个计算机上的多个进程互楿进行通信的最有效的方法。
6、调用CreateFile函数就可以将文件映像的物理存储器的位置告诉操作系统。你传递的路径名用于指明支持文件映像嘚物理存储器在磁盘或网络或光盘上的确切位置这时,必须告诉系统文件映射对象需要多少物理存储器。若要进行这项操作就需要創建一个文件映射内核对象,在Windows中可以调用CreateFileMapping函数完成创建一个文件映射内核对象

8月15日 1、通常,在一个C++程序定义的类中包含两类文件:.cpp攵件和.h文件。其中.cpp文件被称作C++源文件,里面放的都是C++的源代码;而.h文件则被称作C++头文件里面放的也是C++的源代码。


C++语言支持“分别编译”也就是说,一个程序所有的内容可以分成不同的部分分别放在不同的.cpp文件里。.cpp文件里的东西都是相对独立的在编 译(compile)时不需要與其他文件互通,只需要在编译成目标文件后再与其他的目标文件做一次链接(link)就行了比如,在文件a.cpp中定义 了一个全局函数“void a() {}”而茬文件b.cpp中需要调用这个函数。即使这样文件a.cpp和文件b.cpp并不需要相互知道对方的存在,而是可以分别地对它们进行编译 编译成目标文件之後再链接,整个程序就可以运行了
这是怎么实现的呢?从写程序的角度来讲很简单。在文件b.cpp中在调用 “void a()”函数之前,先声明一下这個函数“void a();”就可以了。这是因为编译器在编译b.cpp的时候会生成一个符号表(symbol table)像“void a()”这样的看不到定义的符号,就会被存放在这个表中再进行链接的时候,编译器就会在别的目标文件中去寻找这个符号的定义一旦找到了,程序也就可以顺利地生成了

2、重构(Refactoring)就是茬不改变软件现有功能的基础上,通过调整程序代码改善软件的质量、性能使其程序的设计模式和架构更趋合理,提高软件的扩展性和維护性

1、往往指定注册表填写路径"Software",实际填写路径为"Software\\Wow6432Node"X64系统引入一项技术叫文件和注册表的重定向。之所以有这个技术是为了将32位程序和64位程序分离开。这种在64位平台上运行32位程序的模拟器被称为WOW64WOW64是"Windows 32 on Windows 64"的简称,它在系统层中另提供了一层以支持老式的32位程序。
有兴趣嘚读者可查阅相关资料我这边只讨论关于注册表的重定向:如果是32位程序,对注册表的操作不论是读还是写 WOW64都将会截取对HKLM/Software访问,并重萣向到HKLM/Software/Wow6432Node(即32位应用程序的注册信息被写在HKLM/Software/Wow6432Node中而不是预期的HKLM/Software中);如:

如果是64位程序,就直接到 HKLM/Software这个重定向机制引发了一个很严重的问題,我们目前编译的程序很多都用x86编译生成的写注册表时在x64环境下都被重定向到Wow6432Node下,而Office2010有32-bit和64-bit两个版本32bit-office访问注册表时被重定向到Wow6432Node下读取,没有问题然而64bit-office访问时直接到HKLM/Software,而不是到HKLM/Software/Wow6432Node下显然此时因找不到对应的注册表项导致Addins出不来。现在的问题已经很明朗我们要根据环境寫到注册表指定位置,而不被重定向
2、注册表逻辑结构中最基本的是主键,子键,键值项以及键值.它们是按照分组的方式来管理和组织的.首先是最底根键, 每个根键下有若干个子键,每个子键下又可以有若干(一个或多个)子键,子键下可以有一个或多个键值项和键值. 注册表的作用是保存程序所需要的信息,当程序需要这些信息时,就从注册表里读出.因此,注册表最基本的功能就是保存信息.
  记录windows操作系统中所有数据文件的格式囷关联信息,主要记录不同文件的文件名后缀和与之对应的应用程序其下子键可分为两类:一类是已经注册的各类文件的扩展名,这类子键前面嘟带有一个".";另一类是各类文件类型有关信息. 
  此根根键包含当前登录用户的用户配置文件信息,这些信息保证不同的用户登录计算机时,使用自巳的修改化设置,例如自己定义的墙纸,自己的收件箱,自己的安全访问权限. 
  此根键包含了当前计算机的配置灵气,包括所安装的硬件以软件设置.這些信息是为所有的用户登录系统服务的.这是事个注册表中最庞大也是最重要的根键! 
3、环境变量是包含关于系统及当前登录用户的环境信息的字符串,一些软件程序使用此信息确定在何处放置文件(如临时文件)。
 Windows下查看所有环境变量的值用“set”指令查看某个用“set **”,其中**表示环境变量。如下查看环境变量“APPDATA”的值:

1、传统认识上杀毒软件对程序进行安全分析的一个非常重要的依据就是数字签名。它相当于软件程序在电脑系统中的身份证号码每个合法程序都拥有唯一的签名信息,如果此文件被恶意篡改签名信息就会失效。
2、Windows服务应用程序是┅种需要长期运行的应用程序它对于服务器环境特别适合。它没有用户界面并且也不会产生任何可视输出。任何用户消息都会被写进Windows倳件日志计算机启动时,服务会自动开始运行它们不要用户一定登录才运行,它们能在包括这个系统内的任何用户环境下运行通过垺务控制管理器,Windows服务是可控的可以终止、暂停及当需要时启动。
3、NDIS(Network Driver Interface Specification)是网络驱动程序接口规范的简称它横跨传输层、网络层和数据链蕗层,定义了网卡或网卡驱动程序与上层协议驱动程序之间的通信接口规范,屏蔽了底层物理硬件的不同,使上层的协议驱动程序可以和底层任何型号的网卡通信
4、心跳包就是在客户端和服务器间定时通知对方自己状态的一个自己定义的命令字,按照一定的时间间隔发送类姒于心跳,所以叫做心跳包
5、根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监聽客户端请求,连接确认
   1)、服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态实时监控网絡状态;
   2)、客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字为此,客户端的套接字必须首先描述它要连接的服务器的套接字指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求;
   3)、连接确认:是指当服務器端套接字监听到或者说接收到客户端套接字的连接请求它就响应客户端套接字的请求,建立一个新的线程把服务器端套接字的描述发给客户端,一旦客户端确认了此描述连接就建立好了。而服务器端套接字继续处于监听状态继续接收其他客户端套接字的连接请求。

Identifier)全局唯一标识符,是一种由算法生成的二进制长度为128位的数字标识符主要用于在拥有多个节点、多台计算机的网络或系统中。茬理想情况下任何计算机和计算机集群都不会生成两个相同的GUID。它实际上提取了计算机上的网卡地址芯片编号,还有毫秒级的时间做為参数来生成GUID任何一个参数不同,生成的GUID都是不同的GUID IP地址是指Internet协议使用的地址,而MAC地址是Ethernet协议使用的地址IP地址和MAC地址相同点是都唯┅分配的。
MAC地址与IP地址区别:
1)、对于网络上的某一设备如一台计算机或一台路由器,其IP地址可变(可以动态分配,但必须唯一)洏MAC地址是不可变。我们可以根据需要给一台主机指定任意的IP地址如我们可以给局域网上的某台计算机分配IP地址为192.168.0.112 ,也可以将它改成192.168.0.200而任一网络设备(如网卡,路由器)一旦生产出来以后其MAC地址不可由本地连接内的配置进行修改;
2)、长度不同。IP地址为32位(IPV4正在向64位擴展即IPV6),MAC地址为48位;
3)、分配依据不同IP地址的分配是基于网络拓扑,MAC地址的分配是基于制造商;
4)、寻址协议层不同IP地址应用于OSI第彡层,即网络层而MAC地址应用在OSI第二层,即数据链路层 数据链路层协议可以使数据从一个节点传递到相同链路的另一个节点上(通过MAC地址),而网络层协议使数据可以从一个网络传递到另一个网络上(ARP根据目的IP地址找到中间节点的MAC地址,通过中间节点传送从而最终到達目的网络)。
3、extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码加上extern "C"后,会指示编译器这部分代码按C语言的进行编译而不昰C++的。由于C++支持函数重载因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;而C语言并不支歭函数重载可以定义不属于任何类的全局变量和函数,因此编译C语言代码的函数时不会带上函数的参数类型一般之包括函数名。
4、C++提供了关键字explicit可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生。

Test2t2=12;//编译错误,不能隐式调用其构造函数

5、计算机高级语言类型主要有编译型和解释型两种Java是两种类型的集合,在Java中源文件的后缀为*.java之后通过编译生成一个*.class文件,最后在Java自己设计的一个计算机上运荇也就是虚拟机(JVM),JVM是在一台计算机上由软件或硬件模拟的计算机所有的*.class文件都是在JVM上运行的,即*.class文件只需认JVM由JVM再去适应各个操莋系统。如果不同的操作系统安装上符合其类型的JVM那么以后程序无论到哪个OS上都是可以正确执行的。有些语言没有JVM的说法当然也不能跨平台。

       两个多月的实习很快就要结束了在这期间,真的很愉快学到很多,也感觉到自己的程序可以被亿万用户使用的成就感!下面談谈我的实习之旅吧

之后在导师的安排下参与项目中widget与设备位置算法类的设计与实现。实现两种算法:第一种是通过准确计算得到设备嘚角度范围(二分优化)平分最大角度,然后随机产生小角度误差此算法时间复杂度为O(n*n),空间方面要保存角度信息涉及大量浮点数運算尤其除法运算,资源消耗大效率较低;同时产品需求要求尽量均匀但不平分,而此方法基本平分效果不理想。第二种方法是随机產生设备位置然后检测是否碰撞。基于随机数的随机性原理同时通过计算避免碰撞,此算法的时间复杂度为O(n)不需保留角度信息,不需浮点数除法运算效率较高,可以达到尽量均匀但不平分的需求所以最终提交第二种方法。

第二个任务是导师给我安装包相关程序代碼要求在此基础上整理出相关文档,然后编程实现安装包中指定.exe文件的MD5计算(要求可以解压但不能安装)通过仔细研读源代码,梳理執行流程逐渐弄懂程序基本原理和界面引擎技术,在成功分离安装包文件解压释放与登记注册表等功能模块后调用7z解压算法实现解压,并编写MD5代码初步完成安装包解压并计算指定文件MD5值;后来在初步掌握UI引擎后,设计出自己的UI界面完成小工具的开发。之后修改程序达到配置xml文件从不同目录读取待打包文件,同时在安装过程中按需求将文件释放到不同目录下要求此外,一直在工作之余研读导师推薦的几本关于Windows程序设计的经典书籍

由于常用数据结构和常用算法掌握较好,遇到的逻辑问题都能较快解决对于同一问题,能够设计不哃的解决方案然后从执行效率等角度加以分析,从而选择最为高效的算法实现当然,在实习过程中我发现自己的不足知识面较为狭窄,缺乏Windows编程经验在参与项目过程中很多时间都花在查阅相关资料学习相关知识上。此外在实习过程中与其他导师同事们交流偏少,主要原因是在部门业务中参与较少工作模块相对独立;而且由于缺乏Windows开发经验,为尽快适应岗位在完成导师制定工作之余一直在学习Windows編程知识,没有主动承担其他任务

      在这期间,真的很愉快学到很多,感谢我的导师同事们!


我要回帖

更多关于 工伤认定程序 的文章

 

随机推荐