列个计划:
7.13–7.31 — 尽量看完《C++ Primer 3rd》,一天一章,要把握好时间;
8.1–8.10 — 《密码学》,对整体的概念要清楚,没啥实际用途,仅供吹牛;
8.11-8.20 — 《数据结构》,树的排序和遍历部分代码最好能参照例子写一遍;
8.21-8.31 — 《程序员面试宝典》,细读,深思;
暂定这么多,根据实际执行情况做后续计划。
身上有一个拖拉一年多的小毛病,上周终于有些忍受不了便到医院动了一刀,花钱遭罪不说,本来已经弱不禁风的小身板子大概又瘦了10斤,家人也跟着操了不少的心。
谢谢老婆,不是她的关心,小毛病可能就变成大毛病了;谢谢爸妈,26年来,他们总是无私的疼爱我;谢谢岳父母,他们像关心自己的儿子一样关心着我。
祝自己早日完全康复,也祝愿所有关心我的人和我关心的人身体健康。
Filed Under (心情) by panmaoru on 19-02-2010
回南京,乱糟糟。
Filed Under (心情) by panmaoru on 08-02-2010
风雨不同路,孤江弄扁舟。
Filed Under (心情) by panmaoru on 01-02-2010
顶得住诱惑,耐得住寂寞,受得了挫折。为这三点,佩服下唐僧,他还真爷么。
因为家族产业的缘故,我很少吃小吃店里的包子,这一习惯维持了好多年。
公司早上提供早饭,包子+豆浆。老员工每天都是一个包子+一杯豆浆,刚来的一段时间,我每天早上都拿2个包子,不要自己掏钱的早饭,吃起来具香。差不多一个月过去了,渐渐发觉自己吃不下2个包子了,一个,或者一个半,逐步进入老员工的食量状态。
腻了,真都点腻了。
Test miniposts
Filed Under (未分类) by panmaoru on 12-01-2010
Test miniposts
拖拖拉拉整理完了vc++深入详解的前17章,收获还是不少的。开始写这些文档之前便计划着辞掉那份asp.net的工作,在写这份文档完成之前终于如愿了。从asp.net到win ce,虽然都是vs2005平台,跨度可真不小,从不想整到整不了,一时间很难适应。
《vc++深入详解》是本很不错的书,很仔细的讲解了vc开发的基本知识,本来计划着一口气把书上的例子程序都整理出来,做个笔记,可是因为换了工作,时间上很难保证。另外,书的后三章介绍的分别是active控件,dll,hook与数据库。虽然都是很有用的知识,但是离应用还远,另外,工作上是wince开发,这些知识暂时还用不到,拖拉了一个多星期,也没能把这份文档做个完结。
这两天空闲的时候在想,为了做个了解,干脆粗乱这整理些文字发上来。可是翻开书本的时候却没有多少兴致。罢了,在此做个标记,等回到MFC开发平台的时候再学习这些吧。
为了更快熟悉wince,今天在亚马逊上买了本wince开发的书,不知道每天工作加班到深夜之后,还是否有兴致来整理《win ce 学习笔记》之类的东西。如果时间上容许的话,我肯定乐而为之。好脑筋比不上烂笔头,整理vc++学习笔记过程中思考了一些问题,在面试这份工作的时候提供了不小的帮助。即使抄写比人现成的代码也能给我这只菜鸟带来不小的成就感。
《VC++深入详解–学习笔记》(17)进程间通信
Filed Under (VC++ 学习笔记) by panmaoru on 23-12-2009
当一个进程启动后,操作系统为其分配4GB的私有地址空间,位于同一个进程中的线程共享同一个地址空间。然而由于每个进程所拥有的4GB的地址空间都是私有的,一个进程不能访问另外一个进程的地址空间的数据,因此进程之间的通信相对比较困难。本章将介绍下列4中进程通信的方式:
- 剪贴板
- 匿名通道
- 命名通道
- 邮槽
17.1剪贴板
当我们在一个程序中复制一份数据之后,可以将数据粘贴到另外一个应用程序中,这就是2个进程利用剪贴板实现诗词数据传输。剪贴板实际上是系统维护管理的一块内存区域,当在一个进程中复制数据时,这个份数据被放到该内存区域中,当执行粘帖操作时,从该内存区域中取出数据,然后显示出来。
将数据粘帖上剪切板时,首先要打开剪贴板。
BOOL OpenClipBoard();
当打开剪贴板成功,完成操作之后,需要关闭剪贴板CloseClipBoard(),以便其他程序调用。在系统系统中之后一块剪贴板区域,如果当前拥有者不关闭剪贴板,其他进程则无法获取到。手动将编辑框內数据复制到剪贴板的示例:
void CClipDlg::OnButton1()
{
// TODO: Add your control notification handler code here
if(OpenClipboard())
{
CString str;//用来存放将要放到剪贴板上的数据
HANDLE hClip;//保存GlobalAlloc动态分配的内存对象的句柄
char *pBuf;//保存调用GlobalLock函数返回的地址
EmptyClipboard();//清空剪贴板
GetDlgItemText(IDC_EDIT1,str);//获取编辑框的内容,保存到str
hClip=GlobalAlloc(GMEM_MOVEABLE,str.GetLength()+1);//动态分配内存,返回对象句柄
pBuf=(char*)GlobalLock(hClip);//对内存对象加锁,返回地址
strcpy(pBuf,str);//将str对象中的数据拷贝到pBuf指向的地址空间
GlobalUnlock(hClip);//解锁
SetClipboardData(CF_TEXT,hClip);//以指定的剪贴板格式项剪贴板上存放数据
CloseClipboard();//关闭剪贴板
}
}
其中GlobalAlloc动态分配一块内存区域的参数有几种默认类型,MSDN中给出了详细的说明。
调用剪贴板上的数据,显示到一个编辑框上。
void CClipDlg::OnButton2()
{
// TODO: Add your control notification handler code here
if(OpenClipboard())
{
if(IsClipboardFormatAvailable(CF_TEXT))
{
HANDLE hClip;
char * pBuf;
hClip=GetClipboardData(CF_TEXT);
pBuf=(char*)GlobalLock(hClip);
GlobalUnlock(hClip);
SetDlgItemText(IDC_EDIT2,pBuf);
}
}
}
17.2匿名管道
匿名管道是一个未命名的、单向管道,通常用来在一个父进程和一个子进程之间传输数据。匿名管道只能实现本地机器上的两个进程间的通信,而不能实现跨网络通信。
17.3命名管道
命名管道通过网络来实现进程间的通信,它屏蔽了底层的网络协议细节,在不了解网络协议的情况下也可以利用命名管道来实现进程间的通信。命名管道不仅可以在本机上实现2个进程之间的通信,还可以跨网络实现2个进程的通信。
17.4邮槽
邮槽式基于广播通信体系设计出来的,它采用无连接的不可靠的数据传输。邮槽是一种单向的通信机制,创建邮槽的服务器进程读取数据,打开邮槽的客户端进程写入数据。为了使邮槽在各种Windows平台下运行,传输消息的时候,应该将消息的长度限制在424字节以下。
PS:后三个例子代码写不贴了。
《VC++深入详解–学习笔记》(16)线程同步
Filed Under (VC++ 学习笔记) by panmaoru on 22-12-2009
上一章介绍了线程同步,以及利用互斥对象实现线程同步的方法。本章继续介绍另2种线程同步的方法:事件对象和关键代码段,另外,介绍了利用异步套接字编写网络应用程序的实现。
16.1事件对象
和互斥对象一样,时间对象也属于内核对象。事件对象分为人工重置的事件对象和自动重置的事件对象。人工重置的事件对象得到通知时,等待该事件对象的所有线程都变为可调度线程。自动重置的事件对象得到通知时,等待该事件对象的线程中只有一个变为可调度线程。
HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, // SD BOOL bManualReset, // reset type BOOL bInitialState, // initial state LPCTSTR lpName // object name );
根据事件对象的声明可以了解它的一些参数属性。创建一个事件对象之后,可以通过SetEvent函数和ResetEvent函数来设置事件对象的有无信号状态。通常在单CPU平台下,为了实现线程的通过,常使用自动重置的事件对象,而非人工重置的事件对象。
16.2关键代码段
关键代码段:也称为临界区,工作在用户态,它是指一个小段代码,在代码能够执行前,它必须独占对某些资源的访问权。通常把多线程中访问同一种资源的那部分代码称为关键代码段。利用关键代码段实现线程同步的示例代码如下:
#include <windows.h>
#include <iostream.h>
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
DWORD WINAPI Fun2Proc(LPVOID lpParameter);
int ticket=100;
CRITICAL_SECTION g_cs;
void main()
{
HANDLE hThread1;
HANDLE hThread2;
hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
CloseHandle(hThread1);
CloseHandle(hThread2);
InitializeCriticalSection(&g_cs);//初始化
Sleep(4000);
DeleteCriticalSection(&g_cs);
}
DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
while(TRUE)
{
EnterCriticalSection(&g_cs);//进入关键代码段
Sleep(1);
if(ticket>0)
{
Sleep(1);
cout<<"thread1 sell the ticket:"<<ticket--<<endl;
LeaveCriticalSection(&g_cs);//离开
}
else
{
LeaveCriticalSection(&g_cs);//离开
break;
}
}
return 0;
}
DWORD WINAPI Fun2Proc(LPVOID lpParameter)
{
while(TRUE)
{
EnterCriticalSection(&g_cs);//进入关键代码段
Sleep(1);
if(ticket>0)
{
Sleep(1);
cout<<"thread2 sell the ticket:"<<ticket--<<endl;
LeaveCriticalSection(&g_cs);//离开
}
else
{
LeaveCriticalSection(&g_cs);//离开
break;
}
}
return 0;
}
16.3互斥对象,事件对象和关键代码段的比较
- 互斥对象和事件对象属于内核对象,速度较慢,但是使用这样的内核对象,可以在多个进程中的各个线程间进行同步;
- 关键代码段工作在用户态,速度快。但是使用关键代码段时容易产生死锁,因为在等待进入关键代码段时候无法设定超时值。
