Peter Wu

新的开始

2009年06月21日

原创 Windows Via C/C++ 读书笔记 13 动态链接库基础DLL Basics


Windows Via C/C++ 读书笔记 13 
动态链接库基础DLL Basics1. Overview
本章讲DLL概念(比一些教程仔细得多),实现方式,并给一个简单的DLL例子说明代码如何构建。废话少说,先上图。这张图说明了一个DLL由编写到链接、被调用的全部过程。看这篇文章前,你至少要知道什么是compile,什么是link,都干了些啥。



左边的树是DLL文件的生成过程:
1 编写头文件,包含了需要导出的函数 变量 类型等。
2 编写CPP文件,包含了函数的实现。
3 compile出obj文件。
4-5 Link出一个.dll和一个.lib文件。.dll文件被.exe文件调用。.lib文件只在.exe文件通过隐式调用方式调用DLL文件的时候有用。本章的例子就是个隐式链接方式,还有一种是显示链接通过API在程序运行时动态加载的方式,后面DLL高级部分会讲到。Step9,exe链接的时候讲这个lib文件为什么有用。Lib文件包含了dll导出的函数 变量等信息,阅读全文>

发表于 @ 2009年06月21日 15:51:00|评论(loading...)|举报|收藏

2009年06月18日

原创 Windows Via C/C++ 读书笔记 12 Heap(堆)


Windows Via C/C++ 读书笔记 12 
Heap(堆)1. Overview
堆是除了Reserve-Commit和Memory-Mapped Files外的第三种也是最后一种内存管理方式。它适合用来保存数量很多的小块,优点是不需要做复杂的reserve-commit操作,缺点是不能commit-decommit最大化利用内存。
堆实际上是在进程地址空间中reserve出来的一个地址空间。堆中大部分地址空间是没有commit的(未分配实际内存,见前面章节),当程序在堆上面allocate内存的时候,堆管理器会完成commit操作。用户不再直接reserve-commit,一切由系统代劳了。2. 进程的默认堆(Default Heap)
进程在创建的时候就创建了一个堆,叫做默认堆(Default Heap)。操作系统会在系统函数中使用到这个堆。因为它在进程执行前被创建,进程结束后自动释放,因此用户不能对它做创建和释放操作。系统保证对default heap的访问是串行的,即同一时间只有一个线程在它上面分配或释放内存。
阅读全文>

发表于 @ 2009年06月18日 00:19:00|评论(loading...)|举报|收藏

2009年06月15日

原创 Windows Via C/C++ 读书笔记 11


Windows Via C/C++ 读书笔记 11 
Memory-Mapped Files(内存映射文件)1. Overview
Memroy-Mapped Files(MMFs)是提供一种像访问内存一样访问文件的方案。
Memroy-Mapped Files(MMFs)的作用有3个:
1. 系统用MMFs读取exe和dll文件。还记得前面讲的物理内存和磁盘内存(page files)吗,如果系统需要加载exe和dll文件,把它们都拷贝到内存中,速度是非常慢的。因此,系统采取把exe和dll文件直接转为MMFs,不再做拷贝操作,提高效率。
2. 它本身的特点,访问内存一样访问文件,可以避免烦琐的IO操作,因为可以随意访问文件的任何位置(像访问内存指针一样)。
3. 同一个机器不同进程间共享数据。强大的IPC方法之一,非常常用,也称为共享内存(完全加载到物理内存中,访问速度非常快)。
2. 内存映射exe和dll2.1. 多个程序共享内存映射文件
前面提到,当系统需要执行exe的时候,会把exe阅读全文>

发表于 @ 2009年06月15日 21:10:00|评论(loading...)|举报|收藏

2009年06月14日

原创 Windows Via C/C++ 读书笔记 10

Windows Via C/C++ 读书笔记 10 Windows 内存架构(2)1. 线程的栈当一个线程被创建的时候,操作系统会给它的栈reserve一块区域,通常大小为1M,然后立刻在栈顶commit 2个pages。(见图1)第一个Page是供线程立刻可以使用,第二个page是守护页面(guard page),当线程用完第一个页面的时候,需要更多栈内存会访问到守护页面,操作系统会得到通知。系统会再commit一个页面,把下一个页面作为新的守护页面。(注:非常类似前面讲的例子"reserve and commit memory")。图1 stack初始状态经过一段时间运行后,stack进入图2的状态。图2 stack新状态最底部的页面,图中0x08000000。是不会被线程使用的,一旦试图访问这个区域,操作系统会抛出一个EXCEPTION_STACK_OVERFLOW异常。如果在EXCEPTION_STACK_OVERFLOW异常抛出后还继续访问,系统会接管线程,阅读全文>

发表于 @ 2009年06月14日 09:51:00|评论(loading...)|举报|收藏

2009年06月13日

原创 Windows Via C/C++ 读书笔记 9 Windows Memory Architecture


这章讲进程内存与操作系统物理内存之间的关系,操作系统如何管理。关键字:虚拟地址空间,reserve commit free三步。
Windows Via C/C++ 读书笔记 9 
Windows Memory Architecture 1. 进程的虚拟地址空间
每个进程都有自己的虚地址空间,32bit系统的地址空间是4GB(0x00000000~0xFFFFFFFF),64bit系统是16EB。各个进程的实际地址是操作系统分配的地址加上虚拟空间地址的映射,因为各个进程的实际地址空间被分配在不同的区域,所以各个进程间的地址空间是隔离的,不能互相访问。2. 虚拟地址空间分配

Partition
x86 32-Bit Windows
x86 32-Bit Windows with 3 GB User-Mode
x64 64-Bit Windows
IA-64 64-Bit Windows
NULL-Pointer Assignment
0x00000000
阅读全文>

发表于 @ 2009年06月13日 17:55:00|评论(loading...)|举报|收藏

2009年06月10日

原创 Windows Via C/C++ 读书笔记 8 Fiber(纤程)


Windows Via C/C++ 读书笔记 8 
Fiber(纤程)1. Overview
本章讲UNIX多线程和Windows线程区别,和Fibers的相似。Unix部分是我查资料加个人理解写的,可能有些错误,请达人指正。
UNIX操作系统的多线程实现。这章比较短,查了下UNIX线程的实现。以前知道UNIX只有进程的概念,后来工作又接触了pthreads多线程编程,一直没搞明白。看了下UNIX技术内幕,大概了解了一些,可能还有很多理解不到位的地方,请大家指正。pthreads的实现与fibers非常相似,微软实现fibers的目的就是为了UNIX程序能够快速的过渡过来。
前面章节已经讲了,windows本身是多进程多线程的操作系统,进程和线程都是内核对象。进程间使用不同的内存区域,进程内的线程共享一块内存区域,可以互相访问,而不需要通过复杂的IPC,效率很高。操作系统内核负责线程的调度和管理。
UNIX本身是只有进程的概念,后来UNIX实现提出了2元分化并行。即操作系统提供内核线程和线程库2种多线程方案。在内核线程的基础阅读全文>

发表于 @ 2009年06月10日 09:58:00|评论(loading...)|举报|收藏

2009年06月08日

原创 Windows Via C/C++ 读书笔记 7 异步IO, 完成端口模式

Windows Via C/C++ 读书笔记 7 1. 异步IO异步IO简单来讲就是把读写IO操作调用后交给操作系统处理,调用线程可以继续干其它的事情。当操作系统完成IO操作后,通知调用线程。调用线程得到通知后,再处理。后面会讲如何设置IO模式为异步模式,如何获取通知。操作顺序未知文件的异步IO操作会提交给操作系统的队列,驱动程序不会严格按提交顺序执行。比如有的操作离目前文件指针位置比较近,为了减少磁盘指针移动,可能会先执行这个操作。1.1. OVERLAPPED结构typedef struct _OVERLAPPED {   DWORD  Internal;     // [out] Error code   DWORD  InternalHigh; // [out] Number of bytes transferred   DWORD  Offset;       // [in]  Low 32-bit file offset   DWO阅读全文>

发表于 @ 2009年06月08日 21:19:00|评论(loading...)|举报|收藏

2009年06月05日

原创 Windows Via C/C++ 读书笔记 6


Windows Via C/C++ 读书笔记 6 1. 用内核对象做线程同步1.1. Overview
Why use kernel object?
内核对象做同步操作要进入系统模式,比用户模式更消耗CPU,为什么还要用呢?
内核对象同步操作功能更多,比如跨进程的同步,非阻塞同步等待。

内核对象同步的关键
内核对象有两个状态:"signaled", "nonsignaled"。编程的时候可以"wait"一个内核对象到"signaled"状态才执行。
具有这两种状态的内核对象有:
1. Processes
2. Threads
3. Jobs
4. File and console standard input/output/error streams
5. Events
6. Waitable timers
7. Semaphores
8. Mutexes1.2. Wait函数
前面提到可以"wait"内核对象到"阅读全文>

发表于 @ 2009年06月05日 16:55:00|评论(loading...)|举报|收藏

2009年06月02日

原创 Windows Via C/C++ 读书笔记 5 用户模式的线程同步


Windows Via C/C++ 读书笔记 5 1. 用户模式的线程同步1.1. 原子操作函数
Windows提供几个原子操作函数:
//给变量做加减操作
InterlockedExchangeAdd
InterlockedExchangeAdd64

//修改变量值,返回变量原先值
InterlockedExchange
InterlockedExchange64
InterlockedExchangePointer

//如果变量当前值等于参数3,那么修改该变量为参数1
InterlockedCompareExchange
InterlockedCompareExchangePointer
InterlockedCompareExchange

//加减1
LONG InterlockedIncrement(PLONG plAddend);
LONG InterlockedDecrement阅读全文>

发表于 @ 2009年06月02日 20:34:00|评论(loading...)|举报|收藏

2009年05月27日

原创 Windows Via C/C++ 读书笔记 4 线程调度 优先级


Windows Via C/C++ 读书笔记 4 1. Thread Scheduling, Priorities, and Affinities1.1. 暂停和恢复线程
线程内核对象有一个Suspending计数,每对线程做Suspending操作,该计数加一。
如果该计数不为0,线程不会被执行。
因此要Resume一个线程,必须调用相同次数的Resume操作。
1.2. 暂停和恢复进程
操作系统不提供这样一种方法。作者提供了一个不完美的解决方案:
用CreateToolhelp32Snapshot获取进程的快照信息(包括所有的线程id)
遍历所有的线程,逐个暂停或恢复线程
这么做的问题是,获取进程快照到遍历线程这段时间,可能线程已经被销毁,也可能有新的线程被创建,因此是不可靠的。只有你能保证你的代码不会出现这种情况,才能使用。关键是整个操作不是原子性的,也不能对进程做锁定。
1.3. Sleep
太简单了,不浪费字了1.4. SwitchToThread
相当于阅读全文>

发表于 @ 2009年05月27日 08:44:00|评论(loading...)|举报|收藏

2009年05月25日

原创 Windows Via C/C++ 读书笔记 3


Windows Via C/C++ 读书笔记 3 1. Job
JOB,翻译成工作或者任务。JOB是管理多个进程的集合体。如果你需要一次关闭多个进程,并且要在所有进程退出后得到通知,那么可以使用JOB这种对象。1.1. Job的使用流程
1. 创建JOB或查找一个已有的JOB
2. 把进程加入到JOB中
3. 关闭JOB
4. 等待JOB结束(JOB结束后会处于Signaled状态,因此可以用WaitForSingleObject 等待)2. 线程
线程含有两个东西:
一个内核对象,用于操作系统管理,含有线程的静态信息。和进程内核对象类似。
线程这个东西用了太久了,就不废话了。拣点以前没注意的死角说说。2.1. 线程栈(Thread`s Stack)。
线程栈是有大小的,默认是1M。超过的时候会有"overflow"异常,但是操作系统会捕捉异常,给栈更多的空间,使栈能动态增长。
创建线程的时候可以通过参数设置栈大小,也可以在link选项/STACK中设置,最终取两者中大的一个阅读全文>

发表于 @ 2009年05月25日 20:37:00|评论(loading...)|举报|收藏

2009年05月21日

原创 Windows Via C/C++ 读书笔记 2

Windows Via C/C++ 读书笔记 21. 进程概念进程是一个运行程序的实例。包含2个东东:一个让操作系统管理进程的内核对象。一个地址空间(包含执行代码和数据),也包含动态内存分配的空间。一个进程必须靠线程运行,它至少含有一个线程,即主线程。主线程再来创建更多线程。2. 进程启动Windows有一个启动函数 "XXmianCRTStartup",根据程序类型不同启动函数有所区别。启动函数会调用代码中的"XXmain"入口函数。通过链接指令"/SUBSYSTEM:"可以修改程序类型和入口函数。命令行获取命令行参数//main.cpp#include #include int main(int argc,char **argv){PTSTR pstr=GetCommandLine();阅读全文>

发表于 @ 2009年05月21日 20:04:00|评论(loading...)|举报|收藏

2009年05月17日

原创 windows via C/C++ Read Notes (1) ——Kernel Object (1)

书中假设了一种Windows的进程内核句柄表的实现阅读全文>

发表于 @ 2009年05月17日 08:07:00|评论(loading...)|举报|收藏

2008年05月28日

原创 动态web图形的8种实现方式(转)

动态web图形的8种实现方式 1. SVG 2. Canvas 3. Dynamic images from the server 4. VML 5. Richer Plugin (e.g. Flash) 6. CSS/DOM 7. data: resource 8. XBM 阅读全文>

发表于 @ 2008年05月28日 17:21:00|评论(loading...)|举报|收藏

2007年12月28日

原创 贴几篇python与c++应用的文章

贴几篇python与c++应用的文章C++ 应用程序中 嵌入的python脚本与C++程序的互相调用(访问 通信)http://xjwenjunwu.spaces.live.com/blog/cns!EE28B0FF280F4067!226.entryHP-UX c++ 扩展 python (cpp extend python)http://xjwenjunwu.spaces.live.com/blog/cns!EE28B0FF280F4067!223.entryHP-UX编译python例子Demo/embedhttp://xjwenjunwu.spaces.live.com/blog/cns!EE28B0FF280F4067!222.entry阅读全文>

发表于 @ 2007年12月28日 10:36:00|评论(loading...)|编辑|举报|收藏

Csdn Blog version 3.1a
Copyright © Peter Wu