关于作者

用户名:jerryhuang
笔名:jerryhuang
地区:
行业:其他

日历  

快速登录

+ 用户名:
+ 密 码:

在线留言



编程

资料下载

友情链接

news

访问统计:
文章个数:22
评论个数:9
留言条数:0




Powered by BlogDriver 2.1

Jerryhuang's log

 

路漫漫其修远兮, 吾将上下而求索。 QQ:6232518 MSN:huananhuang@hotmail.com

文章

C++ Builder中如何静态链接,使生成的EXE文件能独立运行?
摘要:C++ Builder中如何静态链接,使生成的EXE文件能独立运行.... 查看全文

- 作者: jerryhuang 2005年06月14日, 星期二 11:14  回复(0) |  引用(0) 加入博采

把信送给加西亚
摘要:这是一篇曾经风靡全世界的文章,当你看到标题可能以为是一个引人入胜、情节精彩的故事,不,不是! 而因为它向我们提出一种办事的方法的思考。 查看全文

- 作者: jerryhuang 2005年04月29日, 星期五 13:20  回复(0) |  引用(0) 加入博采

中国人民很生气,后果很严重!
 起初他们追杀共产主义者,我不是共产主义者,我不说话;
 接着他们追杀犹太人,我不是犹太人,我不说话;
 此后他们追杀工会成员,我不是工会成员,我继续不说话;
 再后来他们追杀天主教徒,我不是天主教徒,我还是不说话;
 最后,他们奔我而来,再也没有人站起来为我说话了。
            ------刻于美国波士顿犹太人被屠杀纪念碑
      日本政要屡次参拜靖国神社、否定二战罪行、淡化和美化侵略史、霸占我钓鱼岛,
 拒不赔偿中国二战受害劳工和齐齐哈尔毒气受害者、侮辱并称要遣送在东京的中国人,
 亚洲金融危机时日元贬值、充当促使人民币升值的急先锋,日本军舰驱赶中国保钓船只和渔船、
 非法扣留保钓人士,暗中支持台独、修改和平宪法,从中阻碍中国的统一大业、出兵伊拉克狼子野心、
 昭然若揭。
 
 作为一个不负责任的国家-日本,如果让他进了联合国常任理事国,那一定是个定时炸弹!
 
 抵制日货从我做起!

- 作者: jerryhuang 2005年04月15日, 星期五 14:38  回复(0) |  引用(0) 加入博采

多线程同步问题小结
   多线程同步问题是编程中的一个难点,其实这个问题在计算机专业的操作系统课程的"信号量与PV操作"就已经学习过理论知识,把理论与实际结合,对于问题的理解会更深刻,实践完也更深知学校课本的东西不是没用,而是没有联系起来。(题外话:高校老师很大一部份没有项目实践经验,害得学生要在期末考试中死记硬背,考完试后脑袋什么也没有记住!)同步问题就是因为线程/进程 间异步执行访问共享数据而引起的数据冲突的问题(经典的例子:生产者与消费者问题),windows提供了一些同步对象来解决此类问题,包括:临界区对象、互斥体对象、事件对象、信号量对象,下面将对这些同步对象进行说明举例。

多线程同步问题是编程中的一个难点,其实这个问题在计算机专业的操作系统课程的"信号量与PV操作"就已经学习过理论知识,
把理论与实际结合,对于问题的理解会更深刻,实践完也更深知学校课本的东西不是没用,而是没有联系起来。(题外话:
高校老师很大一部份没有项目实践经验,害得学生要在期末考试中死记硬背,考完试后脑袋什么也没有记住!)
同步问题就是因为线程/进程 间异步执行访问共享数据而引起的数据冲突的问题(经典的例子:生产者与消费者问题)
,windows提供了一些同步对象来解决此类问题,包括:临界区对象、互斥体对象、事件对象、信号量对象,下面将对这些同步对
象进行说明举例。

Win32 API提供了一组能使线程阻塞其自身执行的等待函数。这些函数在其参数中的一个或多个同步对象产生了信号,或者超过规定的等待时间才会返回。
在等待函数未返回时,线程处于等待状态,此时线程只消耗很少的CPU时间。使用等待函数既可以保证线程的同步,又可以提高程序的运行效率。
最常用的等待函数是:

DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds); //监测单个的同步对象状态

DWORD WaitForMultipleObject(DWORD nCount,CONST HANDLE *lpHandles,BOOL bWaitAll,DWORD dwMilliseconds); //同时监测多个同步对象

这两个函数是线程同步关键的等待函数。

1)临界区对象
临界区对象可以保证同一时刻只有一个线程执行一段访问共享数据结构的代码区(临界区),当一个线程进入临界区,
只有等待该线程执行完临界区代码的指令后,其它线程才能访问临界区的代码,这样就能够有效地保护共享数据的完整性。


class CShareData
{
private:
 char m_buf[MAX];
 CRITICAL_SECTION m_cs;
public:
 CShareData()
 {
  //初始化临界区
   InitializeCriticalSection(&m_cs);
  ...
 }

 ~CShareData()
 {
 }

 read()
 {
  EnterCriticalSection(&m_cs);

  ....

  LeaveCriticalSection(&m_cs);
 }

 write()
 {
  EnterCriticalSection(&m_cs);

  ....

  LeaveCriticalSection(&m_cs);
 }
};

2)事件对象
事件对象有两种状态,无信号状态和有信号状态,在线程访问某一资源之前,需要
等待某一事件发生时,使用事件对象最为适合。

实例:
该实例保证先执行线程1(threadFun1),后执行线程2(threadFun2)

HANDLE hEvent1 = NULL;
HANDLE hEvent2 = NULL;
char g_buf[10] = {0};

DWORD WINAPI threadFun1(LPVOID pParam)
{
 WaitForSingleObject(hEvent1,INFINITE);
 for(int i=0;i<10;i++)
 {
  g_buf[i] = 'a';
  Sleep(200);
 }
 printf("thread1: %s \n",g_buf);
 SetEvent(hEvent2);
 return 0;
}

DWORD WINAPI threadFun2(LPVOID pParam)
{
 //当该函数返回后事件对象自动设置为无信号状态,这样其他线程也将被挂起
 WaitForSingleObject(hEvent2,INFINITE);
 for(int i=0;i<10;i++)
 {
  g_buf[i] = 'b';
  Sleep(200);
 }
 printf("thread2: %s \n",g_buf);
 //SetEvent(hEvent);
 return 0;
}

int main(int argc, char* argv[])
{
 hEvent1 = CreateEvent(NULL, FALSE, FALSE, NULL);
 SetEvent(hEvent1);

 hEvent2 = CreateEvent(NULL, FALSE, FALSE, NULL);

 HANDLE hThread1 = CreateThread(NULL,0,threadFun1,0,0,0);
 HANDLE hThread2 = CreateThread(NULL,0,threadFun2,0,0,0);

 Sleep(5000);
 printf("%s \n",g_buf);
 return 0;
}

3)信号量对象
信号对象允许同时对多个线程共享资源进行访问,在创建对象时指定最大可同时访问的线程数。
当一个线程申请访问成功后,信号对象中的计数器减一,调用ReleaseSemaphore函数后,
信号对象中的计数器加一。其中,计数器值大于或等于0,但小于或等于创建时指定的最大值。
如果一个应用在创建一个信号对象时,将其计数器的初始值设为0,就阻塞了其他线程,保护了资源。
等初始化完成后,调用ReleaseSemaphore函数将其计数器增加至最大值,则可进行正常的存取访问。

经常使用的一个简单的应用例子是判断一个程序是否已经运行了,该内核对象可在不同进程间访问。
实例:

HANDLE hSemaphore;

DWORD WINAPI threadFun1(LPVOID pParam)
{
 WaitForSingleObject(hSemaphore,INFINITE);
 MessageBox(NULL,"thread1","hint",MB_OK);
 ReleaseSemaphore(hSemaphore,1,NULL);
 return 0;
}

DWORD WINAPI threadFun2(LPVOID pParam)
{
 WaitForSingleObject(hSemaphore,INFINITE);
 MessageBox(NULL,"thread2","hint",MB_OK);
 ReleaseSemaphore(hSemaphore,1,NULL);
 return 0;
}


DWORD WINAPI threadFun3(LPVOID pParam)
{
 WaitForSingleObject(hSemaphore,INFINITE);
 MessageBox(NULL,"thread3","hint",MB_OK);
 ReleaseSemaphore(hSemaphore,1,NULL);
 return 0;
}

int main(int argc, char* argv[])
{
 hSemaphore = CreateSemaphore(NULL, 2, 2, NULL);
 
 HANDLE hThread1 = CreateThread(NULL,0,threadFun1,0,0,0);
 HANDLE hThread2 = CreateThread(NULL,0,threadFun2,0,0,0); 
 HANDLE hThread3 = CreateThread(NULL,0,threadFun3,0,0,0);

 Sleep(100000);
 return 0;
}

4)互斥体对象
互斥体对象与临界区对象相似,只是临界区对象只适用于同一个进程中。

- 作者: jerryhuang 2005年04月11日, 星期一 17:48  回复(0) |  引用(0) 加入博采

ASCII对照表
常用ASCII对照表,

- 作者: jerryhuang 2005年03月30日, 星期三 17:42  回复(0) |  引用(0) 加入博采

程序质量的评价和改进
怎样的程序才算有质量的程序, 有质量的程序有评价标准吗,以及作为程序员的我们如何改进我们的程序?
下面是对两种软件设计方法得出的软件评价和改进的小结.

一.结构化设计方法的评价和改进
1.分析评价程序结构的聚合性和耦合性,提高程序的模块独立性.
 聚合性:
 模块内部各部分之间的联系,它描述模块功能的相对强度.(注:模块
 
 耦合性:
 模块与模块之间的联系,它描述模块之间的相对独立性.
 
 原则:
 高内聚,低耦合.
 
 改进方法:
 根据聚合性和耦合性的指标可以对利用结构化设计方法得到的软件结构图进行分析和评价.
为了提高模块的独立性,可能要对软件进行分解和合并,以便改善模块的聚合性和耦合性.分解聚合性弱的模块,合并耦合度高的模块.
 
2.分析评价结构图的深度、宽度、扇出和扇入,改善程序结构的形态特性
 深度:
 结构图的模块层次数叫结构图的深度,一定的程度上反映软件的复杂度,对于中等规模的程序,其深度在10左右,如果大于这个数
则应该考虑结构图中的某些模块是否过于简单.

 宽度:
 结构图中同一层次的最大模块个数称为结构图的宽度,宽度越大系统越复杂.
 
 扇出:
 一个模块直接控制的下属模块的个数称为该模块的扇出数。好的系统的平均扇出数通常是3~4,最多是5~9。
 扇出过大时可以适当增加中间层次的控制模块;扇出过小时可以把下级模块进一步分解成若干个子功能模块,
 或者合并到上级模块中去。当然这种分解或合并不能影响模块的独立性。
 
 扇入:
 多个模块可以有同一个下属模块,该下属模块的上级模块的个数称为扇入数。

 原则:
 通常设计得好的程序结构具有橄榄型结构形态,在这种结构中,顶层扇出比较高,中层扇出比较少,底层(共用模块)扇入比较高。
 
3.分析模块的作用域和控制域,使作用域在控制域之内
 模块的作用域:
 指受其判定影响的所有模块的集合。
 
 模块的控制域:
 指其本身以及所有直接或间接从属于它的模块的集合。
 
 原则:
 在好的程序结构中,所有受判定影响的模块都从属于作出判定的那个模块,最好局限于作出判定的那个模块本身及其直属下级模块。
这样可以明显地降低模块间的耦合性,提高可维护性和可靠性。

4.拟定模块的接口,降低接口的复杂性和冗于度,改善一致性
 模块接口的复杂性是程序出错的一个主要原因,接口的设计应尽量使信息传递简单,并与模块功能一致。

5.分析模块的功能,保证模块的可验证性
 可验证性是软件开发要遵循的基本原理之一,因此模块必须设计成功能可预测的。
 当一个模块可以看作成一个黑盒,不管其内部的处理细节如何,都会产生同样的外部数据时,这种模块是可以预测的。

6.恰当地掌握划分模块的大小
 究竟划分多大的模块最为合理,很难给出绝对的标准。但一般认为,程序最好能够写在一页纸内,
 或者说程序行数在50-100的范围内是比较合适的。同一个问题如果把模块划得 很小,势必增加模块的数量,
 增加了模块接口的复杂性,也增加了花在调用和返回上的时间开销,降低了效率。如果把模块划得过大,
 将会造成测试和维护工作的困难。


二.面向对象设计方法的评价和改进

1.耦合性
 耦合表示类及其对象与其它类及其之间的相互联系。耦合强度可以通过类中对象之间传送的信息的数量和复杂程度来度量。
主要存在两种耦合,交互耦合和继承耦合。

 交互耦合是指类之间的联系是通过消息关联实现的,这种耦合应尽量减少。
 继承耦合是指类及其对象之间的联系是通过继承关系实现的。
 
2.聚合性
 聚合性分操作聚合、类聚合、分类聚合等几种类型。
 
 1)操作聚合
 
 一个操作可以具有一个而且仅仅具有一个功能。具有多个功能的操作或者具有一个功能中的部分功能的操作,都是不可取的。
 面向对象设计中几乎所有单一功能的操作都是很小的,一般只有3~5条语句。语句太多的操作,或者块嵌套太多的操作,
 或者涉及扩展的CASE多条件语句的操作都应该仔细检查,尽量避免。
 
 2)类聚合
 
 在一个类中,其数据变量和操作应该是高聚合的,其中不含无用的数据变量和操作。
 
 3)分类聚合

3.清晰的设计

 由于面向对象设计中强调重用性,清晰的要求就显得更为重要。
设计的清晰与否,与用词一致、遵循已有的协议和避免含混不清的类定义等因素有关。

3.分类结构的深度

 对于中等大小的系统(一般有近100个类)来说,分类结构的层次保持在7层左右。

4.保持类及对象的简明性

 设计方法中很强调简明性,可以从避免多余的数据变量、强调实质内容、避免二义性、
避免类及其对象之间的协同和一个类中避免太多的操作等方面考虑。

5.保持协议的简单性

 消息协议中的参数及其含义尽量保持简单。
如果在协议中出现有关计算机术语,则意味着该类中某些内容可能不属于问题空间,而是与实现有关,应该尽量避免出现这种情况。

6.保持操作的简单性

 面向对象设计中操作一般设计得很小,甚至不足5行源程序语句。
当然,一个操作语句 的多少与具体实现的语言有关,但如果操作的语句超过200个语句,则一定要避免。

7.评价对设计的变动

 评价设计质量的另一条标准是设计维护不变的时间。
如果因为终端用户需求的变化,或现有设计的错误或不足,必须修改设计,那么修改范围的大小和次数就是影响软件设计质量重要因素。
修改范围越大、次数越多,意味着设计质量越差,重用性也越差。一般来说,在设计初始阶段,设计的变动的范围往往是比较大的,
次数也往往是比较多的。

8.使整个系统尽可能小

 一般来说,一个系统所包括的类的个数大约不要超过100。
对于具有好几百个类的系统 来说,由于涉及参与设计的人员太多,就需要形式化的面向对象设计表示、文档及评估标准。
系统太大是很不利于设计的清晰度的,因此应尽量减小系统的大小。

- 作者: jerryhuang 2005年02月2日, 星期三 17:49  回复(0) |  引用(0) 加入博采

61条面向对象设计的经验原则

摘抄自《OOD 启思录》--Arthur J.Riel 著 鲍志云 译


"你不必严格遵守这些原则,违背它们也不会被处以宗教刑罚。但你应当把这些原则看成警铃,若违背了其中的一条,那么警铃就会响起。"

                                                                                  ----------Arthur J.Riel


(1)所有数据都应该隐藏在所在的类的内部。p13
 
(2)类的使用者必须依赖类的共有接口,但类不能依赖它的使用者。p15
 
(3)尽量减少类的协议中的消息。p16
 
(4)实现所有类都理解的最基本公有接口[例如,拷贝操作(深拷贝和浅拷贝)、相等性判断、正确输出内容、从ASCII描述解析等等]。 p16
 
(5)不要把实现细节(例如放置共用代码的私有函数)放到类的公有接口中。p17
如果类的两个方法有一段公共代码,那么就可以创建一个防止这些公共代码的私有函数。
 
(6)不要以用户无法使用或不感兴趣的东西扰乱类的公有接口。p17
 
(7)类之间应该零耦合,或者只有导出耦合关系。也即,一个类要么同另一个类毫无关系,要么只使用另一个类的公有接口中的操作。 p18
 
(8)类应该只表示一个关键抽象。p19
包中的所有类对于同一类性质的变化应该是共同封闭的。一个变化若对一个包影响,则将对包中的所有类产生影响,而对其他的包不造成任何影响 .
 
(9)把相关的数据和行为集中放置。p19
设计者应当留意那些通过get之类操作从别的对象中获取数据的对象。这种类型的行为暗示着这条经验原则被违反了。
 
(10)把不相关的信息放在另一个类中(也即:互不沟通的行为)。p19
朝着稳定的方向进行依赖.
 
(11)确保你为之建模的抽象概念是类,而不只是对象扮演的角色。p23
 
(12)在水平方向上尽可能统一地分布系统功能,也即:按照设计,顶层类应当统一地共享工作。p30
 
(13)在你的系统中不要创建全能类/对象。对名字包含Driver、Manager、System、Susystem的类要特别多加小心。p30
规划一个接口而不是实现一个接口。
 
(14)对公共接口中定义了大量访问方法的类多加小心。大量访问方法意味着相关数据和行为没有集中存放。p30
 
(15)对包含太多互不沟通的行为的类多加小心。p31
这个问题的另一表现是在你的应用程序中的类的公有接口中创建了很多的get和set函数。
 
(16)在由同用户界面交互的面向对象模型构成的应用程序中,模型不应该依赖于界面,界面则应当依赖于模型。p33
 
(17)尽可能地按照现实世界建模(我们常常为了遵守系统功能分布原则、避免全能类原则以及集中放置相关数据和行为的原则而违背这条原则) 。p36
 
(18)从你的设计中去除不需要的类。p38
一般来说,我们会把这个类降级成一个属性。
 
(19)去除系统外的类。p39
系统外的类的特点是,抽象地看它们只往系统领域发送消息但并不接受系统领域内其他类发出的消息。
 
(20)不要把操作变成类。质疑任何名字是动词或者派生自动词的类,特别是只有一个有意义行为的类。考虑一下那个有意义的行为是否应当迁移到已经存在或者尚未发现的某个类中。p40
 
(21)我们在创建应用程序的分析模型时常常引入代理类。在设计阶段,我们常会发现很多代理没有用的,应当去除。p43
 
(22)尽量减少类的协作者的数量。p52
一个类用到的其他类的数目应当尽量少。
 
(23)尽量减少类和协作者之间传递的消息的数量。p55
 
(24)尽量减少类和协作者之间的协作量,也即:减少类和协作者之间传递的不同消息的数量。p55
 
(25)尽量减少类的扇出,也即:减少类定义的消息数和发送的消息数的乘积。p55
 
(26)如果类包含另一个类的对象,那么包含类应当给被包含的对象发送消息。也即:包含关系总是意味着使用关系。p55
 
(27)类中定义的大多数方法都应当在大多数时间里使用大多数数据成员。p57
 
(28)类包含的对象数目不应当超过开发者短期记忆的容量。这个数目常常是6。p57
当类包含多于6个数据成员时,可以把逻辑相关的数据成员划分为一组,然后用一个新的包含类去包含这一组成员。
 
(29)让系统功能在窄而深的继承体系中垂直分布。p58
 
(30)在实现语义约束时,最好根据类定义来实现。这常常会导致类泛滥成灾,在这种情况下,约束应当在类的行为中实现,通常是在构造函数中实现,但不是必须如此。p60
 
(31)在类的构造函数中实现语义约束时,把约束测试放在构造函数领域所允许的尽量深的包含层次中。p60
 
(32)约束所依赖的语义信息如果经常改变,那么最好放在一个集中式的第3方对象中。p60
 
(33)约束所依赖的语义信息如果很少改变,那么最好分布在约束所涉及的各个类中。p60
 
(34)类必须知道它包含什么,但是不能知道谁包含它。p61
 
(35)共享字面范围(也就是被同一个类所包含)的对象相互之间不应当有使用关系。p61
 
(36)继承只应被用来为特化层次结构建模。p74
 
(37)派生类必须知道基类,基类不应该知道关于它们的派生类的任何信息。p74
 
(38)基类中的所有数据都应当是私有的,不要使用保护数据。p75
类的设计者永远都不应该把类的使用者不需要的东西放在公有接口中。
 
(39)在理论上,继承层次体系应当深一点,越深越好。p77
 
(40)在实践中,继承层次体系的深度不应当超出一个普通人的短期记忆能力。一个广为接受的深度值是6。p77
 
(41)所有的抽象类都应当是基类。p81
 
(42)所有的基类都应当是抽象类。p82
 
(43)把数据、行为和/或接口的共性尽可能地放到继承层次体系的高端。p85
 
(44)如果两个或更多个类共享公共数据(但没有公共行为),那么应当把公共数据放在一个类中,每个共享这个数据的类都包含这个类。 p88
 
(45)如果两个或更多个类有共同的数据和行为(就是方法),那么这些类的每一个都应当从一个表示了这些数据和方法的公共基类继承。 p89
 
(46)如果两个或更多个类共享公共接口(指的是消息,而不是方法),那么只有他们需要被多态地使用时,他们才应当从一个公共基类继承。 p89
 
(47)对对象类型的显示的分情况分析一般是错误的。在大多数这样的情况下,设计者应当使用多态。p89
 
(48)对属性值的显示的分情况分析常常是错误的。类应当解耦合成一个继承层次结构,每个属性值都被变换成一个派生类。 p96
 
(49)不要通过继承关系来为类的动态语义建模。试图用静态语义关系来为动态语义建模会导致在运行时切换类型。p97
 
(50)不要把类的对象变成派生类。对任何只有一个实例的派生类都要多加小心。p99
 
(51)如果你觉得需要在运行时刻创建新的类,那么退后一步以认清你要创建的是对象。现在,把这些对象概括成一个类。 p103
 
(52)在派生类中用空方法(也就是什么也不做的方法)来覆写基类中的方法应当是非法的。p103
 
(53)不要把可选包含同对继承的需要相混淆。把可选包含建模成继承会带来泛滥成灾的类。p108
 
(54)在创建继承层次时,试着创建可复用的框架,而不是可复用的组件。p112
 
(55)如果你在设计中使用了多重继承,先假设你犯了错误。如果没犯错误,你需要设法证明。p120
 
(56)只要在面向对象设计中用到了继承,问自己两个问题:(1)派生类是否是它继承的那个东西的一个特殊类型?(2)基类是不是派生类的一部分?p121
 
(57)如果你在一个面向对象设计中发现了多重继承关系,确保没有哪个基类实际上是另一个基类的派生类。p122
 
(58)在面向对象设计中如果你需要在包含关系和关联关系间作出选择,请选择包含关系。p135
 
(59)不要把全局数据或全局函数用于类的对象的薄记工作。应当使用类变量或类方法。p140
 
(60)面向对象设计者不应当让物理设计准则来破坏他们的逻辑设计。但是,在对逻辑设计作出决策的过程中我们经常用到物理设计准则。 p149
 
(61)不要绕开公共接口去修改对象的状态。p164

- 作者: jerryhuang 2005年01月7日, 星期五 14:09  回复(0) |  引用(0) 加入博采

人类进化图

人类进化图


- 作者: jerryhuang 2004年12月22日, 星期三 13:28  回复(1) |  引用(0) 加入博采

windows内核对象
今天重新看了有关I/O完成端口的内容,发现对windows内核对象有些忘了,所以重新拾起Jeffrey的经典之作《windows核心编程》
的第三章温习。

windows内核对象
今天重新看了有关I/O完成端口的内容,发现对windows内核对象有些忘了,所以重新拾起Jeffrey的经典之作《windows核心编程》
的第三章温习。

理解windows内核对象有什么意义呢?
Jeffrey说:"准备理解windows内核对象对于想要成为一名windows软件开发能手的人来说至关重要。"

什么是windows内核对象?
windows内核对象比如:存取符号对象、事件对象、文件对象,文件映象对象、I/O完成端口对象、进程对象、线程对象、互斥对象等。
每个内核对象都只是内核分配的一个内存块,并且只能由内核来访问。该内存是一种数据结构,它的成员维护
该对象的各种信息。有些数据成员所有的内核对象都相同,但绝大多数的数据成员属于特定的内核对象。
上面说的内核对象只能由内核访问,那应用程序也就无法在内存中找到内核对象的数据结构,并直接改变它们的内容,这样做的目的是
为了确保内核对象结构保持状态的一致。这个限制也使Microsoft能够在不破坏任何应用程序的情况下在这些结构中添加、删除和修改数
据成员。其实这种保护数据的思想是采用面向对象的思想,面向对象的封装性。

既然无法直接改变这些数据结构,那么应用程序如何才能操作这些内核对象呢?
Windows提供了一组函数(相当于面向对象的对象方法),以及创建一个内核对象返回的"句柄"(handle),来操作内核对象的数据结构。

注:句柄只是句柄表字段中的一个索引字段(句柄表一定也含内核对象的内存地址字段)。

内核对象的使用计数
内核对象由内核所拥有,而不是由进程所有。换句话说,如果你的进程调用了一个创建内核对象的函数,然后你终止运行,那么内核对象不
一定撤消,有可能另一个进程正在使用你的进程创建的内核对象。内核使用计数来保存有多少个进程在使用某个内核对象,一个进程访问一
现有的内核对象,引用计数+1,当进程终止,引用计数-1,如果引用计数为0,内核撤消该对象。

安全性
除了内核对象外,应用程序也有使用其他类型对象,如菜单、窗口、刷子、字体等。这些属于用户对象和GDI对象,不属于内核对象。
怎么区分"用户对象、GDI对象"与"内核对象区别"?
观察创建该对象所用的函数,是否设定安全属性的信息(PSECURITY_ATTRIBUTES参数)。

- 作者: jerryhuang 2004年11月29日, 星期一 17:35  回复(0) |  引用(0) 加入博采

系统权限数据库设计实例
系统权限数据库设计实例:
基于角色的访问控制方法。是目前公认的解决大型企业的统一资源访问控制的有效方法。
其显著的两大特征是:
1.减小授权管理的复杂性,降低管理开销。
2.灵活地支持企业的安全策略,并对企业的变化有很大的伸缩性。

系统权限数据库设计实例:
基于角色的访问控制方法。是目前公认的解决大型企业的统一资源访问控制的有效方法。
其显著的两大特征是:
1.减小授权管理的复杂性,降低管理开销。
2.灵活地支持企业的安全策略,并对企业的变化有很大的伸缩性。

user :用户表
role :角色表
group :组表
right :权限表
role_right :角色-组表
user_role :用户权限表
group_role :角色-组表
 
角色:是权限的一个集合。
组:是角色的一集合。

user:
ID
name
-----------------
 
role:
ID
name
-------------------------
 
group:
ID
name

----------------------------
 
right:
ID
name
pid (父权限)
----------------------
 
role_right:
ID
role_id
permission_id
--------------------------
 
user_role:(实现用户与权限的分离(直接相关),而是通过角色间接与权限相关。)
ID
user_id
role_id
------------------------------
 
group_role:
ID
role_id
group_id
-----------------------
 
 

- 作者: jerryhuang 2004年11月18日, 星期四 17:38  回复(3) |  引用(0) 加入博采