导航:首页 > 编程语言 > window多线程编程

window多线程编程

发布时间:2022-09-18 19:14:57

‘壹’ 多线程编程里的thread.sleep问题

thread.sleep(0) 或3,只是让CPU能切换下时间片,有机会腾出CPU让别人执行。
window的计时最小是以15ms做为单位的,以15ms递增的,所以可以有15,30,45,15倍数的精度,而且是在上下浮动,设为30可能是15,可能是45(主要看cpu忙不忙)。

‘贰’ windows环境,多线程情况下,C语言向文件写入数据。

①、对于你能写这么长的问题描述,说明你很认真。

②、你的目的性较强,但是你也想有更加明确的目标,我可以给你讲一下怎么自己去寻找目标和路线以及怎样学习。

③、计算机专业领域一共有几个大方向,十几个分支方向,而每个分支方向又有几十个小方向,每一个方向的深入学习与熟练到一定火候都不是一朝一夕,互相之间也不是完全没联系的,但是你现在就应该选择一个大方向并在其中的一个小方向内深入(为什么要这么早就选择具体的分支方向?后面说)。

④、这里列出计算机的几个大方向(非编程开发类的我就不说了):
基本方向:
1、单片机、嵌入式方向
2、网络编程:涉及到服务器程序、客户端开发、脚本设计等。
3、系统编程:基础API开发、桌面开发、系统程序开发、服务程序
4、图形学:3D、2D、图像识别、人脸识别
5、音频:语音识别、音频解码、音频软件
6、编译原理:编译器设计、脚本解释器、虚拟机、非自然语言翻译系统
7、应用层开发:利用高层语言去开发表层应用
8、安全:反工程、病毒、反病毒、木马、反木马、软件破解、软件加壳
附加方向:
8、人工智能:遗传算法、神经网络、灰色系统等等
9、游戏设计:各种游戏引擎设计以及业务逻辑设计等

⑤、基本方向是你一定要选的,附加方向只是基于基本方向的一些锦上添花,但是不管你怎么选,最开始某些东西一定要深入而不是只是懂就够(当然你对自己要求似乎不会很低),我把这个列出来:

数据结构:下面其他理论的基础。
操作系统原理:理解操作系统的架构和细节,你才能对以后关于多线程、文件管理、内存管理、指令优先级等有一个正确理解和运用。
编译原理:能够升华你对计算机编程语言的理解,对以后出现的各种编译、解释、兼容、移植、优化、并发与并行算法等有一个深入理解。
数据库系统原理:这个是进入公司都要会的,也是大型软件开发的基础。
软件工程:这个是你能够在经验不足还能保证大项目正常完成的理论基础。
网络技术:这个是必须学的,因为目前几乎没有一款装几率很高的软件或者平台跟网络无关。

数学的话,主要是:离散数学、线性代数、高等数学、计算机图形学、概率论

以上几个基础就是你成为一个融汇各个主要分支牛人必须学的(当然不是指理论,而是理论+实践编码能力)

⑥以上都是大的基础,要一一攻破并深入学习,虽然网络时代计算机专业知识爆炸式的增长,但是以上几个基础掌握后,会发现,以后的什么新的理论和技术都是基于这些大基础,你就很容易理解了。

⑦我为什么开头不讲你要具体学什么怎么顺序学呢?因为那些技术你要掌握的话,根本可以自己解决,但是如果你由于兴趣,沉迷于一些自己可见的小范围技术的话,那么毕业后虽然也能找到不错的工作,薪水也可能高,但是不能成为一个大牛。

现在才开始讲学习顺序,虽然你说不要推荐书,不过我还是要用书来做顺序。
C语言是可以写很多核心和高级的东西,而不只是小东西,但是从你代码来看,居然用到了 goto,我不是说你那些程序用到GOTO有什么不好,而是一定要避免用GOTO,goto是错误之源,如果你有什么内容非要用到goto才能写到,说明你的编码技巧还有不少提高空间。

你的学习顺序应该是:
C:做一个超级马里奥出来,并能够读取文本脚本来更新关卡。
C++:写一个2D图形引擎,封装掉细节,实现面向对象设计和可复用设计,并且用到《设计模式》中提到的一些设计模式,这样才能算对C++有一个很好的掌握。
MFC:MFC技术虽然近期已经冷下来了,但是你能熟练掌握它,才能证明你的C++OO技术够纯熟,严格证明你掌握了MFC很简单,你只要用MFC做出一个杀毒引擎就差不多了。推荐的书有《深入浅出MFC》。
《Windows程序设计》:和MFC不同的是,用的是windows核心SDK,也就是API,这本书学完后,你才能从操作系统层面上算掌握了win32 平台下的机理(其实win64和win32大部分机理类似)。
C#:C#里集合了当代和前沿计算机科学里最先进的一些语法(虽然执行效率一直被人质疑),但是你学完C#并深入后,至少能够算是对计算机语言有一个更加深刻的理解了。如何证明你C#学的不错了?也很简单,再次写一个随便什么游戏,比如俄罗斯方块。如果更加证明自己呢?用它写一个P2P网络对战游戏。

(如果你注意的话,会发现我说的学习顺序都是沿着语言和某些技术的,为什么呢?因为这些语言和技术涉及到特定的领域技术和计算机理论思想,比如学完了C#的话,就不单指学完了C#,而是把多种语言范式都学习了一遍,以及现代的程序开发思维(因为里面用到了很多让你一劳永逸的技术))

以上5个步骤都是基础大步骤,要解决的话要没1-2年应该不够。
与此同时,要尽快选出文中你感兴趣的方向作为3-5年的长期方向,不要担心过早选择分支方向会有什么损失,因为计算机很多分支是相通的,只有你把分支方向深入进去,才能真正理解很多理论的实践意义。并且一旦你在某个分支领域形成了较强的优势(比如,到公司里只有你这方面最强),那么你就是稀缺人才。

关于大方向的步骤就不说了,你主要就是要把我说的这几个基础步骤先解决,同时平时要注重大方向理论结合实际去编码和开发。

‘叁’ 为什么运行程序的时候不能干别的

一、问题的提出
编写一个耗时的单线程程序:
新建一个基于对话框的应用程序SingleThread,在主对话框IDD_SINGLETHREAD_DIALOG添加一个按钮,ID为IDC_SLEEP_SIX_SECOND,标题为“延时6秒”,添加按钮的响应函数,代码如下:

void CSingleThreadDlg::OnSleepSixSecond()
{
Sleep(6000); //延时6秒
}

编译并运行应用程序,单击“延时6秒”按钮,你就会发现在这6秒期间程序就象“死机”一样,不在响应其它消息。为了更好地处理这种耗时的操作,我们有必要学习——多线程编程。

二、多线程概述
进程和线程都是操作系统的概念。进程是应用程序的执行实例,每个进程是由私有的虚拟地址空间、代码、数据和其它各种系统资源组成,进程在运行过程中创建的资源随着进程的终止而被销毁,所使用的系统资源在进程终止时被释放或关闭。
线程是进程内部的一个执行单元。系统创建好进程后,实际上就启动执行了该进程的主执行线程,主执行线程以函数地址形式,比如说main或WinMain函数,将程序的启动点提供给Windows系统。主执行线程终止了,进程也就随之终止。
每一个进程至少有一个主执行线程,它无需由用户去主动创建,是由系统自动创建的。用户根据需要在应用程序中创建其它线程,多个线程并发地运行于同一个进程中。一个进程中的所有线程都在该进程的虚拟地址空间中,共同使用这些虚拟地址空间、全局变量和系统资源,所以线程间的通讯非常方便,多线程技术的应用也较为广泛。
多线程可以实现并行处理,避免了某项任务长时间占用CPU时间。要说明的一点是,目前大多数的计算机都是单处理器(CPU)的,为了运行所有这些线程,操作系统为每个独立线程安排一些CPU时间,操作系统以轮换方式向线程提供时间片,这就给人一种假象,好象这些线程都在同时运行。由此可见,如果两个非常活跃的线程为了抢夺对CPU的控制权,在线程切换时会消耗很多的CPU资源,反而会降低系统的性能。这一点在多线程编程时应该注意。
Win32 SDK函数支持进行多线程的程序设计,并提供了操作系统原理中的各种同步、互斥和临界区等操作。Visual C++ 6.0中,使用MFC类库也实现了多线程的程序设计,使得多线程编程更加方便。

三、Win32 API对多线程编程的支持

Win32 提供了一系列的API函数来完成线程的创建、挂起、恢复、终结以及通信等工作。下面将选取其中的一些重要函数进行说明。

1、HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId);

该函数在其调用进程的进程空间里创建一个新的线程,并返回已建线程的句柄,其中各参数说明如下:
lpThreadAttributes:指向一个 SECURITY_ATTRIBUTES 结构的指针,该结构决定了线程的安全属性,一般置为 NULL;
dwStackSize:指定了线程的堆栈深度,一般都设置为0;
lpStartAddress:表示新线程开始执行时代码所在函数的地址,即线程的起始地址。一般情况为(LPTHREAD_START_ROUTINE)ThreadFunc,ThreadFunc 是线程函数名;
lpParameter:指定了线程执行时传送给线程的32位参数,即线程函数的参数;
dwCreationFlags:控制线程创建的附加标志,可以取两种值。如果该参数为0,线程在被创建后就会立即开始执行;如果该参数为CREATE_SUSPENDED,则系统产生线程后,该线程处于挂起状态,并不马上执行,直至函数ResumeThread被调用;
lpThreadId:该参数返回所创建线程的ID;如果创建成功则返回线程的句柄,否则返回NULL。

2、DWORD SuspendThread(HANDLE hThread);
该函数用于挂起指定的线程,如果函数执行成功,则线程的执行被终止。

3、DWORD ResumeThread(HANDLE hThread);
该函数用于结束线程的挂起状态,执行线程。

4、VOID ExitThread(DWORD dwExitCode);
该函数用于线程终结自身的执行,主要在线程的执行函数中被调用。其中参数dwExitCode用来设置线程的退出码。

5、BOOL TerminateThread(HANDLE hThread,DWORD dwExitCode);
一般情况下,线程运行结束之后,线程函数正常返回,但是应用程序可以调用TerminateThread强行终止某一线程的执行。各参数含义如下:
hThread:将被终结的线程的句柄;
dwExitCode:用于指定线程的退出码。
使用TerminateThread()终止某个线程的执行是不安全的,可能会引起系统不稳定;虽然该函数立即终止线程的执行,但并不释放线程所占用的资源。因此,一般不建议使用该函数。

6、BOOL PostThreadMessage(DWORD idThread,
UINT Msg,
WPARAM wParam,
LPARAM lParam);
该函数将一条消息放入到指定线程的消息队列中,并且不等到消息被该线程处理时便返回。
idThread:将接收消息的线程的ID;
Msg:指定用来发送的消息;
wParam:同消息有关的字参数;
lParam:同消息有关的长参数;
调用该函数时,如果即将接收消息的线程没有创建消息循环,则该函数执行失败。

四、Win32 API多线程编程例程

例程1 MultiThread1
建立一个基于对话框的工程MultiThread1,在对话框IDD_MULTITHREAD1_DIALOG中加入两个按钮和一个编辑框,两个按钮的ID分别是IDC_START,IDC_STOP ,标题分别为“启动”,“停止”,IDC_STOP的属性选中Disabled;编辑框的ID为IDC_TIME ,属性选中Read-only;
在MultiThread1Dlg.h文件中添加线程函数声明: void ThreadFunc();
注意,线程函数的声明应在类CMultiThread1Dlg的外部。 在类CMultiThread1Dlg内部添加protected型变量: HANDLE hThread;DWORD ThreadID;分别代表线程的句柄和ID。
在MultiThread1Dlg.cpp文件中添加全局变量m_bRun:volatile BOOL m_bRun;m_bRun 代表线程是否正在运行。
你要留意到全局变量 m_bRun 是使用 volatile 修饰符的,volatile 修饰符的作用是告诉编译器无需对该变量作任何的优化,即无需将它放到一个寄存器中,并且该值可被外部改变。对于多线程引用的全局变量来说,volatile 是一个非常重要的修饰符。

编写线程函数:
void ThreadFunc()
{
CTime time;
CString strTime;
m_bRun=TRUE;
while(m_bRun)
{
time=CTime::GetCurrentTime();
strTime=time.Format("%H:%M:%S");
::SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_TIME,strTime);
Sleep(1000);
}
}

该线程函数没有参数,也不返回函数值。只要m_bRun为TRUE,线程一直运行。
双击IDC_START按钮,完成该按钮的消息函数: void CMultiThread1Dlg::OnStart()
{
// TODO: Add your control notification handler code here
hThread=CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)ThreadFunc,
NULL,
0,
&ThreadID);
GetDlgItem(IDC_START)->EnableWindow(FALSE);
GetDlgItem(IDC_STOP)->EnableWindow(TRUE);

}

双击IDC_STOP按钮,完成该按钮的消息函数: void CMultiThread1Dlg::OnStop()
{
// TODO: Add your control notification handler code here
m_bRun=FALSE;
GetDlgItem(IDC_START)->EnableWindow(TRUE);
GetDlgItem(IDC_STOP)->EnableWindow(FALSE);
}

编译并运行该例程,体会使用Win32 API编写的多线程。

例程2 MultiThread2
该线程演示了如何传送一个一个整型的参数到一个线程中,以及如何等待一个线程完成处理。
建立一个基于对话框的工程MultiThread2,在对话框IDD_MULTITHREAD2_DIALOG中加入一个编辑框和一个按钮,ID分别是IDC_COUNT,IDC_START ,按钮控件的标题为“开始”; 在MultiThread2Dlg.h文件中添加线程函数声明: void ThreadFunc(int integer);注意,线程函数的声明应在类CMultiThread2Dlg的外部。在类CMultiThread2Dlg内部添加protected型变量: HANDLE hThread;DWORD ThreadID;分别代表线程的句柄和ID。打开ClassWizard,为编辑框IDC_COUNT添加int型变量m_nCount。
在MultiThread2Dlg.cpp文件中添加:
void ThreadFunc(int integer)
{
int i;
for(i=0;i<integer;i++)
{
Beep(200,50);
Sleep(1000);
}
}

双击IDC_START按钮,完成该按钮的消息函数:
void CMultiThread2Dlg::OnStart()
{
UpdateData(TRUE);
int integer=m_nCount;
hThread=CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)ThreadFunc,
(VOID*)integer,
0,
&ThreadID);
GetDlgItem(IDC_START)->EnableWindow(FALSE);
WaitForSingleObject(hThread,INFINITE);
GetDlgItem(IDC_START)->EnableWindow(TRUE);
}

顺便说一下WaitForSingleObject函数,其函数原型为:DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds);
hHandle为要监视的对象(一般为同步对象,也可以是线程)的句柄;
dwMilliseconds为hHandle对象所设置的超时值,单位为毫秒;
当在某一线程中调用该函数时,线程暂时挂起,系统监视hHandle所指向的对象的状态。如果在挂起的dwMilliseconds毫秒内,线程所等待的对象变为有信号状态,则该函数立即返回;如果超时时间已经到达dwMilliseconds毫秒,但hHandle所指向的对象还没有变成有信号状态,函数照样返回。参数dwMilliseconds有两个具有特殊意义的值:0和INFINITE。若为0,则该函数立即返回;若为INFINITE,则线程一直被挂起,直到hHandle所指向的对象变为有信号状态时为止。
本例程调用该函数的作用是按下IDC_START按钮后,一直等到线程返回,再恢复IDC_START按钮正常状态。编译运行该例程并细心体会。

例程3 MultiThread3
传送一个结构体给一个线程函数也是可能的,可以通过传送一个指向结构体的指针参数来完成。先定义一个结构体:
typedef struct
{
int firstArgu,
long secondArgu,

}myType,*pMyType;

创建线程时CreateThread(NULL,0,threadFunc,pMyType,…);
在threadFunc函数内部,可以使用“强制转换”:
int intValue=((pMyType)lpvoid)->firstArgu;
long longValue=((pMyType)lpvoid)->seconddArgu;
……

MultiThread3将演示如何传送一个指向结构体的指针参数。
建立一个基于对话框的工程MultiThread3,在对话框IDD_MULTITHREAD3_DIALOG中加入一个编辑框IDC_MILLISECOND,一个按钮IDC_START,标题为“开始” ,一个进度条IDC_PROGRESS1;打开ClassWizard,为编辑框IDC_MILLISECOND添加int型变量m_nMilliSecond,为进度条IDC_PROGRESS1添加CProgressCtrl型变量m_ctrlProgress;
在MultiThread3Dlg.h文件中添加一个结构的定义:
struct threadInfo
{
UINT nMilliSecond;
CProgressCtrl* pctrlProgress;
};

线程函数的声明: UINT ThreadFunc(LPVOID lpParam);
注意,二者应在类CMultiThread3Dlg的外部。
在类CMultiThread3Dlg内部添加protected型变量: HANDLE hThread;DWORD ThreadID;分别代表线程的句柄和ID。
在MultiThread3Dlg.cpp文件中进行如下操作:
定义公共变量 threadInfo Info;
双击按钮IDC_START,添加相应消息处理函数:
void CMultiThread3Dlg::OnStart()
{
// TODO: Add your control notification handler code here

UpdateData(TRUE);
Info.nMilliSecond=m_nMilliSecond;
Info.pctrlProgress=&m_ctrlProgress;

hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc,&Info,0,&ThreadID);
/*
GetDlgItem(IDC_START)->EnableWindow(FALSE);
WaitForSingleObject(hThread,INFINITE);
GetDlgItem(IDC_START)->EnableWindow(TRUE);
*/
}

在函数BOOL CMultiThread3Dlg::OnInitDialog()中添加语句:
{
……
// TODO: Add extra initialization here
m_ctrlProgress.SetRange(0,99);
m_nMilliSecond=10;
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
}

添加线程处理函数:
UINT ThreadFunc(LPVOID lpParam) {
threadInfo* pInfo=(threadInfo*)lpParam;
for(int i=0;i<100;i++)
{
int nTemp=pInfo->nMilliSecond;

pInfo->pctrlProgress->SetPos(i);

Sleep(nTemp);
}
return 0;
}

顺便补充一点,如果你在void CMultiThread3Dlg::OnStart() 函数中添加/* */语句,编译运行你就会发现进度条不进行刷新,主线程也停止了反应。什么原因呢?这是因为WaitForSingleObject函数等待子线程(ThreadFunc)结束时,导致了线程死锁。因为WaitForSingleObject函数会将主线程挂起(任何消息都得不到处理),而子线程ThreadFunc正在设置进度条,一直在等待主线程将刷新消息处理完毕返回才会检测通知事件。这样两个线程都在互相等待,死锁发生了,编程时应注意避免。

例程4 MultiThread4
该例程测试在Windows下最多可创建线程的数目。
建立一个基于对话框的工程MultiThread4,在对话框IDD_MULTITHREAD4_DIALOG中加入一个按钮IDC_TEST和一个编辑框IDC_COUNT,按钮标题为“测试” , 编辑框属性选中Read-only;在MultiThread4Dlg.cpp文件中进行如下操作:添加公共变量volatile BOOL m_bRunFlag=TRUE; 该变量表示是否还能继续创建线程。
添加线程函数:
DWORD WINAPI threadFunc(LPVOID threadNum)
{
while(m_bRunFlag)
{
Sleep(3000);
}
return 0;
}

只要 m_bRunFlag 变量为TRUE,线程一直运行。
双击按钮IDC_TEST,添加其响应消息函数:
void CMultiThread4Dlg::OnTest()
{
DWORD threadID;
GetDlgItem(IDC_TEST)->EnableWindow(FALSE);
long nCount=0;
while(m_bRunFlag)
{
if(CreateThread(NULL,0,threadFunc,NULL,0,&threadID)==NULL)
{
m_bRunFlag=FALSE;
break;
}
else
{
nCount++;
}
}
//不断创建线程,直到再不能创建为止
m_nCount=nCount;
UpdateData(FALSE);
Sleep(5000);
//延时5秒,等待所有创建的线程结束
GetDlgItem(IDC_TEST)->EnableWindow(TRUE);
m_bRunFlag=TRUE;
}

五、MFC对多线程编程的支持
MFC中有两类线程,分别称之为工作者线程和用户界面线程。二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环。
工作者线程没有消息机制,通常用来执行后台计算和维护任务,如冗长的计算过程,打印机的后台打印等。用户界面线程一般用于处理独立于其他线程执行之外的用户输入,响应用户及系统所产生的事件和消息等。但对于Win32的API编程而言,这两种线程是没有区别的,它们都只需线程的启动地址即可启动线程来执行任务。
在MFC中,一般用全局函数AfxBeginThread()来创建并初始化一个线程的运行,该函数有两种重载形式,分别用于创建工作者线程和用户界面线程。两种重载函数原型和参数分别说明如下:

(1) CWinThread* AfxBeginThread(AFX_THREADPROC pfnThreadProc,
LPVOID pParam,
nPriority=THREAD_PRIORITY_NORMAL,
UINT nStackSize=0,
DWORD dwCreateFlags=0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL);

PfnThreadProc:指向工作者线程的执行函数的指针,线程函数原型必须声明如下:
UINT ExecutingFunction(LPVOID pParam);
请注意,ExecutingFunction()应返回一个UINT类型的值,用以指明该函数结束的原因。一般情况下,返回0表明执行成功。
pParam:传递给线程函数的一个32位参数,执行函数将用某种方式解释该值。它可以是数值,或是指向一个结构的指针,甚至可以被忽略;
nPriority:线程的优先级。如果为0,则线程与其父线程具有相同的优先级;
nStackSize:线程为自己分配堆栈的大小,其单位为字节。如果nStackSize被设为0,则线程的堆栈被设置成与父线程堆栈相同大小;
dwCreateFlags:如果为0,则线程在创建后立刻开始执行。如果为CREATE_SUSPEND,则线程在创建后立刻被挂起;
lpSecurityAttrs:线程的安全属性指针,一般为NULL;

(2) CWinThread* AfxBeginThread(CRuntimeClass* pThreadClass,
int nPriority=THREAD_PRIORITY_NORMAL,
UINT nStackSize=0,
DWORD dwCreateFlags=0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL);

pThreadClass 是指向 CWinThread 的一个导出类的运行时类对象的指针,该导出类定义了被创建的用户界面线程的启动、退出等;其它参数的意义同形式1。使用函数的这个原型生成的线程也有消息机制,在以后的例子中我们将发现同主线程的机制几乎一样。
下面我们对CWinThread类的数据成员及常用函数进行简要说明。
m_hThread:当前线程的句柄;
m_nThreadID:当前线程的ID;
m_pMainWnd:指向应用程序主窗口的指针
BOOL CWinThread::CreateThread(DWORD dwCreateFlags=0,
UINT nStackSize=0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL);
该函数中的dwCreateFlags、nStackSize、lpSecurityAttrs参数和API函数CreateThread中的对应参数有相同含义,该函数执行成功,返回非0值,否则返回0。
一般情况下,调用AfxBeginThread()来一次性地创建并启动一个线程,但是也可以通过两步法来创建线程:首先创建CWinThread类的一个对象,然后调用该对象的成员函数CreateThread()来启动该线程。

virtual BOOL CWinThread::InitInstance();

重载该函数以控制用户界面线程实例的初始化。初始化成功则返回非0值,否则返回0。用户界面线程经常重载该函数,工作者线程一般不使用InitInstance()。 virtual int CWinThread::ExitInstance();
在线程终结前重载该函数进行一些必要的清理工作。该函数返回线程的退出码,0表示执行成功,非0值用来标识各种错误。同InitInstance()成员函数一样,该函数也只适用于用户界面线程。

六、MFC多线程编程实例
在Visual C++ 6.0编程环境中,我们既可以编写C风格的32位Win32应用程序,也可以利用MFC类库编写C++风格的应用程序,二者各有其优缺点。基于Win32的应用程序执行代码小巧,运行效率高,但要求程序员编写的代码较多,且需要管理系统提供给程序的所有资源;而基于MFC类库的应用程序可以快速建立起应用程序,类库为程序员提供了大量的封装类,而且Developer Studio为程序员提供了一些工具来管理用户源程序,其缺点是类库代码很庞大。由于使用类库所带来的快速、简捷和功能强大等优越性,因此除非有特殊的需要,否则Visual C++推荐使用MFC类库进行程序开发。
我们知道,MFC中的线程分为两种:用户界面线程和工作者线程。我们将分别举例说明。
用 MFC 类库编程实现工作者线程

例程5 MultiThread5
为了与Win32 API对照,我们使用MFC 类库编程实现例程3 MultiThread3。
建立一个基于对话框的工程MultiThread5,在对话框IDD_MULTITHREAD5_DIALOG中加入一个编辑框IDC_MILLISECOND,一个按钮IDC_START,标题为“开始” ,一个进度条IDC_PROGRESS1;打开ClassWizard,为编辑框IDC_MILLISECOND添加int型变量m_nMilliSecond,为进度条IDC_PROGRESS1添加CProgressCtrl型变量m_ctrlProgress;
在MultiThread5Dlg.h文件中添加一个结构的定义:
struct threadInfo
{
UINT nMilliSecond;
CProgressCtrl* pctrlProgress;
};

线程函数的声明:UINT ThreadFunc(LPVOID lpParam);
注意,二者应在类CMultiThread5Dlg的外部。
在类CMultiThread5Dlg内部添加protected型变量:CWinThread* pThread;
在MultiThread5Dlg.cpp文件中进行如下操作:定义公共变量:threadInfo Info;
双击按钮IDC_START,添加相应消息处理函数:

void CMultiThread5Dlg::OnStart()
{
// TODO: Add your control notification handler code here

UpdateData(TRUE);
Info.nMilliSecond=m_nMilliSecond;
Info.pctrlProgress=&m_ctrlProgress;

pThread=AfxBeginThread(ThreadFunc,
&Info);
}

在函数BOOL CMultiThread3Dlg::OnInitDialog()中添加语句: {
……

// TODO: Add extra initialization here
m_ctrlProgress.SetRange(0,99);
m_nMilliSecond=10;
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
}

添加线程处理函数:
UINT ThreadFunc(LPVOID lpParam)
{
threadInfo* pInfo=(threadInfo*)lpParam;
for(int i=0;i<100;i++)
{
int nTemp=pInfo->nMilliSecond;

pInfo->pctrlProgress->SetPos(i);

Sleep(nTemp);
}
return 0;
}

用 MFC 类库编程实现用户界面线程
创建用户界面线程的步骤:使用ClassWizard创建类CWinThread的派生类(以CUIThread类为例)
class CUIThread : public CWinThread
{
DECLARE_DYNCREATE(CUIThread)
protected:
CUIThread(); // protected constructor used by dynamic creation

// Attributes
public:

// Operations
public:

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CUIThread)
public:
virtual BOOL InitInstance();
virtual int ExitInstance();
//}}AFX_VIRTUAL

// Implementation
protected:
virtual ~CUIThread();

// Generated message map functions
//{{AFX_MSG(CUIThread)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
};

重载函数InitInstance()和ExitInstance()。 BOOL CUIThread::InitInstance()
{
CFrameWnd* wnd=new CFrameWnd;
wnd->Create(NULL,"UI Thread Window");
wnd->ShowWindow(SW_SHOW);
wnd->UpdateWindow();
m_pMainWnd=wnd;
return TRUE;
}

创建新的用户界面线程 void CUIThreadDlg::OnButton1()
{
CUIThread* pThread=new CUIThread();
pThread->CreateThread();
}

请注意以下两点:
A、在UIThreadDlg.cpp的开头加入语句: #include "UIThread.h"
B、把UIThread.h中类CUIThread()的构造函数的特性由 protected 改为 public。
用户界面线程的执行次序与应用程序主线程相同,首先调用用户界面线程类的InitInstance()函数,如果返回TRUE,继续调用线程的Run()函数,该函数的作用是运行一个标准的消息循环,并且当收到WM_QUIT消息后中断,在消息循环过程中,Run()函数检测到线程空闲时(没有消息),也将调用OnIdle()函数,最后Run()函数返回,MFC调用ExitInstance()函数清理资源。
你可以创建一个没有界面而有消息循环的线程,例如:你可以从CWinThread派生一个新类,在InitInstance函数中完成某项任务并返回FALSE,这表示仅执行InitInstance函数中的任务而不执行消息循环,你可以通过这种方法,完成一个工作者线程的功能。

‘肆’ MFC编程相对于其它编windows程难多少是不是MFC使用限制的比较多呢

学WTL吧,MFC真是逐步落伍了。
WTL 在开发者之间的悄悄传播已经超过一年了, 传闻它是基于ATL的,并在微软内部使用.这理所当然的引起了ATL开发者社区的主意.这些人从ATL1.1开始,就一直为ATL控件书写UI代码,但是他们发现,他们的所写的代码常常就是纯的Win32 GDI代码.我告诉您, WTL并没有多大不同.

是不是让人失望? 不,因为ATL只是对COM进行了简单的封装,这也是ATL的强大之处. 是的,写ATL您必须通晓COM. 您在ATL上额外花费的功夫跟您学习COM所作的努力比起来,简直微不足道.这跟那些需要把主要精力花费在学习类库本身,忽略COM的库是完全不同的.

WTL与此类似.您需要懂得Win32窗口技术和GDI.只要您懂得,学习WTL就似清风抚面,再简单不过了.如果您不懂 这些,那么您最好使用VB来写UI代码.

WTL有什么?

它给各种类型的应用程序提供了一个基本的框架.注意,虽然您没有MFC那样的文档/视结构,但是您有视(views). 在WTL有大量的代码让您来管理视,而且加入您自己的代码也很容易. WTL有AppWizard,可以让您生成SDI, MDI 和多线程SDI程序多线程SDI跟IE或Windows Explorer很像.它看起来是打开了多个程序实例,实际上这些窗口都是属于一个进程的).

另外,您的程序可以是基于对话框的,也可以是基于视的.视可以是基于CWindowImpl的,也可以是基于控件,甚至是IE里的一个HTML页.您可以选择您的程序是否需要一个rebar, command bar (CE-like), toolbar 和/或status bar.另外,您的程序可以主持ActiveX控件,以及成为一个COM服务器.

这里有几个关于视的选项. WTL提供splitter窗口类(这样在一个视里您可以有两个窗口)和scroll窗口类(这样您的窗口可以比它显示的"视"小). WTL也有个类似MFC的UpDateUI的东西,但是它们不是很一样 - 主要的区别是您需要把需要更新的项用宏映射标注出来,然后您在您的类里加入执行UpdateUI的代码. DDX/DDV在WTL也支持,同样类似MFC,但有不同. 您必须加一个宏映射来实现DoDataExchange,然后加入调用它的代码.

现在WTL也有GDI类了.然而,HDC的封装类就像CWindow一样,只进行了很简单的封装 - 它几乎没有加入任何新的功能.不过,在WTL,你可以得到播放meta文件和OpenGL支持. 最有价值的我猜应该是打印机DC的那些继承类 - WTL有打印机支持,甚至打印预览. 当然也有GDI对象的封装. 诸如画笔,画刷,区域等.

WTL对所有的Win32 (和W2K) 通用对话框进行了封装.同样尽管简单,但是它的确使请求字体或者文件变的非常的简单.
合成了旧的AtlControls.h,新加了一些封装类. 这些封装类封装了W2K控件,以及一些不属于Win32的"控件",像Command Bar, bitmap button, hyperlink 和 wait cursor.

WTL 最终把消息分离带入了ATL! 一些新的MSG映射宏将消息分离,调用您类里的消息处理函数.消息处理函数的参数的值是从消息分离得到的.唯一令人头痛的是,您需要查看头文件以确定函数参数的意义.

最后,WTL还有一些实用类.最重要的是CString. 不错,它是从MFC克隆得到的( on write),具有(在我知道的范围内)MFC版本的所有方法.还有查找文件的API的封装类,以及CRect, CSize and CPoint.

‘伍’ 各位QT大侠: QT多线程编程的时候,怎么把次线程处理好的数据实时的显示到ui上去

Qt上要求界面处理一般需要在主线程中完成。
所以最好把次线程中的数据缓冲区放到主线程中:
1、一种方式可以进行数据拷贝,但肯定效率低了。
2、另一种方式是直接将数据缓冲区放到主线程中,然后在主线程中处理读取数据槽。但这样可能主线程压力大,机器配置不能太低。
3、直接在主线程中访问次线程的数据并刷新界面,不过这处理起来复杂(需要手工同步),容易出错。
4、将TableWidget指针传入次线程中,直接在次线程中对其进行操作并发送刷新信号。这种方式未经验证,感觉可能性不大:一方面指针容易走空,另一方面就是前面说的限制在主线程中对接面进行处理。不过所说的“处理”可能并不包括刷新数据吧。
期待楼主进行验证,并展示结果。(或者楼主可以将UDP试验项目发送给我,让我试试,QQ:956693152,谢谢!)

‘陆’ 想学IT应该买什么书看

首先,我觉得你需要明确自己的发展方向,你想学习的课程起码串联起来是个完整的体系,以后能够帮助你就业

书籍整理如下:

C++开发

1.《C++ Primer》:全面学习C++的必备书籍

2.《Thinking in C++》:了解C++背后的一些机制

3.《深度探索C++对象模型》:深入了解C++,也是学习COM的必经之路

Windows平台

入门

1.《Windows程序设计》:这本书主要讲的是Windows API的使用,是Windows编程入门书籍。上册涉及到的知识基本上就够用了,时间不充裕的话阅读上册即可。

2.《Win32多线程程序设计》:Windows下多线程编程必备

3.《Windows核心编程》:Window平台基础知识:消息机制,内存管理,多线程,动态链接库等

4.《Windows网络编程》:介绍Windows下各种网络协议的开发和并发处理模型。

进阶

1.《深入浅出MFC》:Windows下编程,MFC虽然有些过时,但其机制还是有学习的价值。重点学习书中提到的MFC 6大机制

2.《COM本质论》:COM是Windows构建用户态的重要技术之一,Windows开发必修课,本书对COM的设计动机作了深入阐述

3.《深入解析ATL》:ATL全名Active Templete Library,是用C++的模版封装了COM,这本书主要讲的是对源码分析

4.《WTL White Paper》:WTL源自微软,基于ATL的一套开源模版库,主要用于界面编程和工具类的使用

5.《代码大全》:这边书主要讲的是工程编码规范

高级

1.《深入解析Windows操作系统》:Windows大牛书籍,讲的主要是Windows操作系统的内核原理

调试技术

1.《软件调试》

2.《Windows高级调试》

3.《windows用户态程序高效排错》

Linux平台

Linux内核

1.《Linux Kernel Development》/《Linux内核设计与实现》:Robert Love的着作,不厚的一本书,深入浅出地将Linux内核娓娓道来

Linux使用和Shell编程

1.《sed & awk》/《sed与awk》:sed与awk都是Linux下常用的日志分析利器

Linux编程

1.《Beginning Linux Programming》/《Linux程序设计》:老牌的Linux编程入门书

2.《Advanced Programming in the Unix Environment》/《Unix环境高级编程》:对Unix编程环境做了细致的总结,涵盖了进程间通讯、网络通讯、文件系统等各方面的知识

网络编程

1.《TCP/IP Illustrated, Volume I》/《TCP/IP详解,卷一》:对理解TCP/IP协议的设计理念和协议细节有显着的帮助。

2.《Unix Network Programming》/《Unix网络编程》,卷一、卷二:网络编程方面难以逾越的着作,事无巨细、深入浅出,强烈推荐

对这些书目抱有100%的信心,全部掌握,融会贯通,即可打通奇经八脉,天下无双。

对了,你没有基础最好从c与c++基础开始。找些基础书开始看。

[C语言入门经典(第四版)].(美)霍顿.扫描版,《C++ Primer》就不错。

‘柒’ 通过线程句柄和ID能获得进程的句柄和ID吗

在Windows中,句柄是一个系统内部数据结构的引用。例如,当你操作一个窗口,或说是一个Delphi窗体时,系统会给你一个该窗口的句柄,系统会通知你:你正在操作142号窗口,就此,你的应用程序就能要求系统对142号窗口进行操作——移动窗口、改变窗口大小、把窗口极小化为图标,等等。实际上许多Windows API函数把句柄作为它的第一个参数,如GDI(图形设备接口)句柄、菜单句柄、实例句柄、位图句柄等等,不仅仅局限于窗口函数。

换句话说,句柄是一种内部代码,通过它能引用受系统控制的特殊元素,如窗口、位图、图标、内存块、光标、字体、菜单等等。

案例:获取窗口句柄

案例说明

本例实现窗口句柄的获取。

实现过程

Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long

Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Private Declare Function SetLayeredWindowAttributes Lib "user32" (ByVal hwnd As Long, ByVal crKey As Long, ByVal bAlpha As Byte, ByVal dwFlags As Long) As Long

Private Const WS_EX_LAYERED = &H80000

Private Const GWL_EXSTYLE = (-20)

Private Const LWA_ALPHA = &H2

Private Sub Form_Activate()

On Error Resume Next

For i = 0 To 150 Step 2.5

SetLayeredWindowAttributes Me.hwnd, 0, i, LWA_ALPHA

DoEvents

Next i

End Sub

Private Sub Form_load()

Dim rtn As Long

rtn = GetWindowLong(Me.hwnd, GWL_EXSTYLE)

rtn = rtn Or WS_EX_LAYERED

SetWindowLong Me.hwnd, GWL_EXSTYLE, rtn

SetLayeredWindowAttributes Me.hwnd, 0, 0, LWA_ALPHA

End Sub

单从概念上讲,句柄指一个对象的标识,而指针是一个对象的首地址。从实际处理的角度讲,即可以把句柄定义为指针,又可以把它定义为同类对象数组的索引,这两种处理方法都有优缺点,至于选用哪种方式,完全应该看实际需要,这可以说是一种程序设计上的技巧。那种单纯认为句柄是指针或索引的想法都是机械的、不确切的。

其实,在Windows中类似的处理是很多的、很灵活的。再具个相似的例子:

我们知道,在Windows中有个函数叫做CallWindowProc。顾名思义,它的作用就是向指定的窗口过程传递一个消息。你也许会想,既然我已经有了窗口过程的指针,为什么我不可以直接通过这个指针调用该函数(这是C语言的内建功能)?事实上,在Win16中确实可以这么做,因为GetWindowLong返回的确实是该函数的指针。但在Win32下,GetWindowLong返回的并不是该函数的指针,而是一个包含函数指针的数据结构的指针(MSDN上说返回的是一个窗口函数地址或它的句柄,就是指的这种情况)。该数据结构是可变的,但只要你使用CallWindowProc来调用的话是不会出错的。这里我们又看到使用句柄处理带来的好处。(补充说明一点:微软在这里之所以这么处理,是为了解决16位/32位以及ANSI/UNICODE的转化问题)

1.句柄是什么?

在windows中,句柄是和对象一一对应的32位无符号整数值。对象可以映射到唯

一的句柄,句柄也可以映射到唯一的对象。

2.为什么我们需要句柄?

更准确地说,是windows需要句柄。windows需要向程序员提供必要地编程接口

,在这些接口中,允许程序员访问、创建和销毁对象。但是,出于封装地考虑,wi

ndows并不想向程序员返回指针。指针包含了太多的信息。首先指针给出了对象存储

的确切位置;其次,要操作一个指针,程序员必须知道指针所指对象的内部结构特

征,也即,windows必须向程序员暴露相应的数据结构,而这些数据结构也许是操作

系统想向程序员隐藏的。

如果说COM技术向用户隐藏了数据,只暴露了接口并只允许按接口定义的方法操

作数据的话,句柄这种方式则允许你按自己的方式直接操作数据,但windows又不向

你直接暴露数据。直接操作数据是程序员需要的,不暴露数据是windows所需要的,

句柄封装方式实现了各取所需。

3.句柄如何与对象映射?

封装背后,必须有一个地方可以实现解码,以实现句柄和对象的相互转换。在

windows中,存在两种映射方式:

a. 全等映射。也即,句柄本身就是一个指针。映射在这里只是类型转换而已。

这种情况有,进程实例句柄或模块句柄,以及资源句柄等等。

b. 基于表格的映射。这是对象指针与句柄之间最普通的映射机制。操作系统创

建表格,并保存所有要考虑的对象。需要创建新对象时,要先在表格中找到空入口

,然后把表示对象的数据添入其中。当对象被删除时,它的数据成员和其在表中的

入口被释放。

4.句柄的定义和实现

我们以GDI对象为例进行讨论。创建了GDI对象,就会得到该对象的句柄。句柄

的对象可能是HBRUSH、HPEN、HFONT或HDC中的一种,这依赖于你创建 的GDI对象类

型。但是最普通的GDI对象类型是HGDIOBJ。HGDIOBJ被定义成空指针。

HPEN的实际编译类型定义随编译时间宏STRICT的不同而不同。如果STRCIT已经

被定义了,HPEN是这样的:

struct HPEN__ {int unused};

typedef struct HPEN__* HPEN;

如果STRICT没有定义,HPEN是这样定义的:

typedef void *HANDLE;

typedef HANDLE HPEN;

上面这段代码是一个注重细节的程序员最接近句柄的地方,因此我们重点分析

一下。这里有一点点技巧。如果定义了STRICT宏,HPEN是指向有单个未使用字段的

结构的指针,否则HPEN是空指针。C/C++编译器允许把任何类型的指针作为空指什传

递,反之则不可以。两个不同类型的非空指针是互不兼容的。在STRICT版本中,编

译对GDI对象句柄的不正确混用将给出警告,对于非GDI句柄,如HWND、HMENU的不正

确混用也会给出警告,从而使程序在编译器得到更STRICT的检查。

接下来的分析可能不那么令你感兴趣,但它更深刻地揭示了句柄。对GDI句柄来

说,尽管windows头文件把它定义成指针,但如果你仔细检查这些句柄的值,它根本

就不像指针,这也是为什么我说它只是一个32位无符整数值的原因。对句柄就是指

针的情况,这句话也仍然适用。让我们随意地生成一些句柄,比如你用GetStockOb

ject()以得到一些句柄,你会发现,它们的值总在区间0x01900011到0xba040389。

前者指向用户区中的未分配的无效区域,后者指向内核地址空间。另外你可能发现

,两个句柄之间的值可能只差数值1,这也说明GDI句柄不是指针。

和多数人想象的不一样,句柄也不是一个单纯的索引值。对GDI对象句柄来说,

GDI句柄由8位 、1位堆对象标记(表明对象是否创建在堆中)、7位对象类型信息和

高4位为0的16位索引组成,如图:

3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0

1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0

| 8 位引用计数 |堆 | 对象类型7 | 16位索引 |





在这里你可以看到,对GDI来说,它只使用了16位作为索引。这意味着一个进程最多只

可以创建小于64K个句柄,实际上受其他一些限制,整个Windows系统中大概可以容纳约

16384(0x4000)个GDI对象。
============================
进程ID
ID是英文IDentity的缩写,ID是身份标识号码的意思很多设备都有的一个识别好吗比如说硬盘就有id号,所有的商品都有一个id,正规的应该是唯一的
identification,意思是身份,身份证用的是这个词,
还有你在网上登陆论坛什么的,都有个虚拟的ID,就像是你的身份证一样,用以区别,你的昵称可以和别人的相同但是ID确不能相同的。
进程ID顾名思义
知道进程ID我们可以结束进程
进程对象是一种内核对象,每个内核对象实际上是由内核分配的一块内存,而且只能由内核来访问。这一内存块是一个数据结构,它的成员包含有关于该对象的信息。因为内核对象只能由内核访问,所以应用程序不可能在内存中定位这些数据结构和直接改变它们的内容。为了达到操纵这些内核对象的目的,win32API以良好的方式提供了一组操纵这些结构的函数,对内核对象的访问总是通过这些函数,当调用创建内核对象的函数时,函数返回一个标志该对象的句柄,它是一个32位的数值,可以被进程中的任意线程使用,可以把它传给各种WIN32函数,这样系统就知道想要操纵的是哪一个内核对象。

而进程被创建时,系统会赋给它一个唯一的标识符,就是进程ID。系统中运行的其他进程不会有相同的ID值,这个值也是可以被使用的,例如父进程可以通过创建子进程时得到的ID来和子进程通信。
==========================================
所谓句柄实际上是一个数据,是一个Long (整长型)的数据。

句柄是WONDOWS用来标识被应用程序所建立或使用的对象的唯一整数,WINDOWS使用各种各样的句柄标识诸如应用程序实例,窗口,控制,位图,GDI对象等等。WINDOWS句柄有点象C语言中的文件句柄。

从上面的定义中的我们可以看到,句柄是一个标识符,是拿来标识对象或者项目的,它就象我们的姓名一样,每个人都会有一个,不同的人的姓名不一样,但是,也可能有一个名字和你一样的人。从数据类型上来看它只是一个16位的无符号整数。应用程序几乎总是通过调用一个WINDOWS函数来获得一个句柄,之后其他的WINDOWS函数就可以使用该句柄,以引用相应的对象。

如果想更透彻一点地认识句柄,我可以告诉大家,句柄是一种指向指针的指针。我们知道,所谓指针是一种内存地址。应用程序启动后,组成这个程序的各对象是住留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址访问对象。但是,如果您真的这样认为,那么您就大错特错了。我们知道,Windows是一个以虚拟内存为基础的操作系统。在这种系统环境下,Windows内存管理器经常在内存中来回移动对象,依此来满足各种应用程序的内存需要。对象被移动意味着它的地址变化了。如果地址总是如此变化,我们该到哪里去找该对象呢?

为了解决这个问题,Windows操作系统为各应用程序腾出一些内存储地址,用来专门登记各应用对象在内存中的地址变化,而这个地址(存储单元的位置)本身是不变的。Windows内存管理器在移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。这样我们只需记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。这个地址是在对象装载(Load)时由系统分配给的,当系统卸载时(Unload)又释放给系统。

句柄地址(稳定)→记载着对象在内存中的地址————→对象在内存中的地址(不稳定)→实际对象

本质:WINDOWS程序中并不是用物理地址来标识一个内存块,文件,任务或动态装入模块的,相反的,WINDOWS API给这些项目分配确定的句柄,并将句柄返回给应用程序,然后通过句柄来进行操作。

但是必须注意的是程序每次从新启动,系统不能保证分配给这个程序的句柄还是原来的那个句柄,而且绝大多数情况的确不一样的。假如我们把进入电影院看电影看成是一个应用程序的启动运行,那么系统给应用程序分配的句柄总是不一样,这和每次电影院售给我们的门票总是不同的一个座位是一样的道理。

线程是指程序的一个指令执行序列,WIN32 平台支持多线程程序,允许程序中存在多个线程。 在单 CPU 系统中,系统把 CPU 的时间片按照调度算法分配给各个线程,因此各线程实际上是分时执行的,在多 CPU 的 Windows NT 系统中, 同一个程序的不同线程可以被分配到不同的 CPU 上去执行。由于一个程序的各线程是在相同的地址空间运行的,因此设及到了如何共享内存, 如何通信等问题,这样便需要处理各线程之间的同步问题,这是多线程编程中的一个难点。

线程,也被称为轻量进程(lightweight processes)。计算机科学术语,指运行中的程序的调度单位。

线程是进程中的实体,一个进程可以拥有多个线程,一个线程必须有一个父进程。线程不拥有系统资源,只有运行必须的一些数据结构;它与父进程的其它线程共享该进程所拥有的全部资源。线程可以创建和撤消线程,从而实现程序的并发执行。一般,线程具有就绪、阻塞和运行三种基本状态。

在多中央处理器的系统里,不同线程可以同时在不同的中央处理器上运行,甚至当它们属于同一个进程时也是如此。大多数支持多处理器的操作系统都提供编程接口来让进程可以控制自己的线程与各处理器之间的关联度(affinity)。

进程是程序在一个数据集合上运行的过程(注:一个程序有可能同时属于

多个进程),它是操作系统进行资源分配和调度的一个独立单位,进程可以简单的分为系统进程(包括一般

Windows程序和服务进程)和用户进程

句柄:用于唯一标识资源(例如文件和注册表项)的值,以便程序可以访问它。
线程:在运行程序指令的进程中的对象,线程允许在进程中进行并发操作,并使一个进程能在不同处理器上同时运行其程序的不同部分。
进程:一个可执行程序(如WINDOWS资源管理器)或一种服务(如MSTask)。

‘捌’ 如何使用 AfxBeginThread创建MFC线程对象和Win32线程对象

一、问题的提出
编写一个耗时的单线程程序:
新建一个基于对话框的应用程序SingleThread,在主对话框IDD_SINGLETHREAD_DIALOG添加一个按钮,ID为IDC_SLEEP_SIX_SECOND,标题为

“延时6秒”,添加按钮的响应函数,代码如下:

void CSingleThreadDlg::OnSleepSixSecond()
{
Sleep(6000); //延时6秒
}
编译并运行应用程序,单击“延时6秒”按钮,你就会发现在这6秒期间程序就象“死机”一样,不在响应其它消息。为了更好地处理这种

耗时的操作,我们有必要学习——多线程编程。
二、多线程概述
进程和线程都是操作系统的概念。进程是应用程序的执行实例,每个进程是由私有的虚拟地址空间、代码、数据和其它各种系统资源组成

,进程在运行过程中创建的资源随着进程的终止而被销毁,所使用的系统资源在进程终止时被释放或关闭。
线程是进程内部的一个执行单元。系统创建好进程后,实际上就启动执行了该进程的主执行线程,主执行线程以函数地址形式,比如说

main或WinMain函数,将程序的启动点提供给Windows系统。主执行线程终止了,进程也就随之终止。
每一个进程至少有一个主执行线程,它无需由用户去主动创建,是由系统自动创建的。用户根据需要在应用程序中创建其它线程,多个线程并发地运行于同一个进程中。一个进程中的所有线程都在该进程的虚拟地址空间中,共同使用这些虚拟地址空间、全局变量和系统资源,所

以线程间的通讯非常方便,多线程技术的应用也较为广泛。
多线程可以实现并行处理,避免了某项任务长时间占用CPU时间。要说明的一点是,目前大多数的计算机都是单处理器(CPU)的,为了运行所有这些线程,操作系统为每个独立线程安排一些CPU时间,操作系统以轮换方式向线程提供时间片,这就给人一种假象,好象这些线程都在

同时运行。由此可见,如果两个非常活跃的线程为了抢夺对CPU的控制权,在线程切换时会消耗很多的CPU资源,反而会降低系统的性能。这一点在多线程编程时应该注意。
Win32 SDK函数支持进行多线程的程序设计,并提供了操作系统原理中的各种同步、互斥和临界区等操作。Visual C++6.0中,使用MFC类库也实现了多线程的程序设计,使得多线程编程更加方便。
三、Win32 API对多线程编程的支持
Win32 提供了一系列的API函数来完成线程的创建、挂起、恢复、终结以及通信等工作。下面将选取其中的一些重要函数进行说明。
1、HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId);
该函数在其调用进程的进程空间里创建一个新的线程,并返回已建线程的句柄,其中各参数说明如下:
lpThreadAttributes:指向一个 SECURITY_ATTRIBUTES 结构的指针,该结构决定了线程的安全属性,一般置为 NULL;
dwStackSize:指定了线程的堆栈深度,一般都设置为0;
lpStartAddress:表示新线程开始执行时代码所在函数的地址,即线程的起始地址。一般情况为(LPTHREAD_START_ROUTINE)ThreadFunc,

ThreadFunc
是线程函数名;
lpParameter:指定了线程执行时传送给线程的32位参数,即线程函数的参数;
dwCreationFlags:控制线程创建的附加标志,可以取两种值。如果该参数为0,线程在被创建后就会立即开始执行;如果该参数为CREATE_SUSPENDED,则系统产生线程后,该线程处于挂起状态,并不马上执行,直至函数ResumeThread被调用;

lpThreadId:该参数返回所创建线程的ID;
如果创建成功则返回线程的句柄,否则返回NULL。
2、DWORD SuspendThread(HANDLE hThread);
该函数用于挂起指定的线程,如果函数执行成功,则线程的执行被终止。 3、DWORD ResumeThread(HANDLE hThread);
该函数用于结束线程的挂起状态,执行线程。
4、VOID ExitThread(DWORD dwExitCode);
该函数用于线程终结自身的执行,主要在线程的执行函数中被调用。其中参数dwExitCode用来设置线程的退出码。
5、BOOL TerminateThread(HANDLE hThread,DWORD dwExitCode);
一般情况下,线程运行结束之后,线程函数正常返回,但是应用程序可以调用TerminateThread强行终止某一线程的执行。各参数含义如下:
hThread:将被终结的线程的句柄;
dwExitCode:用于指定线程的退出码。
使用TerminateThread()终止某个线程的执行是不安全的,可能会引起系统不稳定;虽然该函数立即终止线程的执行,但并不释放线程所占用的资源。因此,一般不建议使用该函数。

6、BOOL PostThreadMessage(DWORD idThread,
UINT Msg,
WPARAM wParam,
LPARAM lParam);
该函数将一条消息放入到指定线程的消息队列中,并且不等到消息被该线程处理时便返回。
idThread:将接收消息的线程的ID;
Msg:指定用来发送的消息;
wParam:同消息有关的字参数;
lParam:同消息有关的长参数;
调用该函数时,如果即将接收消息的线程没有创建消息循环,则该函数执行失败。
四、Win32 API多线程编程例程
例程1 MultiThread1
建立一个基于对话框的工程MultiThread1,在对话框IDD_MULTITHREAD1_DIALOG中加入两个按钮和一个编辑框,两个按钮的ID分别是IDC_START,IDC_STOP
,标题分别为“启动”,“停止”,IDC_STOP的属性选中Disabled;编辑框的ID为IDC_TIME ,属性选中Read-only;

在MultiThread1Dlg.h文件中添加线程函数声明: void ThreadFunc();
注意,线程函数的声明应在类CMultiThread1Dlg的外部。在类CMultiThread1Dlg内部添加protected型变量: HANDLE
hThread;
DWORD ThreadID;
分别代表线程的句柄和ID。

在MultiThread1Dlg.cpp文件中添加全局变量m_bRun : volatile BOOL m_bRun;
m_bRun 代表线程是否正在运行。
你要留意到全局变量 m_bRun 是使用 volatile 修饰符的,volatile
修饰符的作用是告诉编译器无需对该变量作任何的优化,即无需将它放到一个寄存器中,并且该值可被外部改变。对于多线程引用的全局变量

来说,volatile
是一个非常重要的修饰符。
编写线程函数: void ThreadFunc()
{
CTime time;
CString strTime;
m_bRun=TRUE;
while(m_bRun)
{
time=CTime::GetCurrentTime();
strTime=time.Format("%H:%M:%S");
::SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_TIME,strTime);
Sleep(1000);
}
}
该线程函数没有参数,也不返回函数值。只要m_bRun为TRUE,线程一直运行。
双击IDC_START按钮,完成该按钮的消息函数:
void CMultiThread1Dlg::OnStart()
{
// TODO: Add your control notification handler code here
hThread=CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)ThreadFunc,
NULL,
0,
&ThreadID);
GetDlgItem(IDC_START)->EnableWindow(FALSE);
GetDlgItem(IDC_STOP)->EnableWindow(TRUE);
}
双击IDC_STOP按钮,完成该按钮的消息函数: void CMultiThread1Dlg::OnStop()
{
// TODO: Add your control notification handler code here
m_bRun=FALSE;
GetDlgItem(IDC_START)->EnableWindow(TRUE);
GetDlgItem(IDC_STOP)->EnableWindow(FALSE);
}
编译并运行该例程,体会使用Win32 API编写的多线程。

例程2 MultiThread2
该线程演示了如何传送一个一个整型的参数到一个线程中,以及如何等待一个线程完成处理。
建立一个基于对话框的工程MultiThread2,在对话框IDD_MULTITHREAD2_DIALOG中加入一个编辑框和一个按钮,ID分别是IDC_COUNT,IDC_START
,按钮控件的标题为“开始”;
在MultiThread2Dlg.h文件中添加线程函数声明: void ThreadFunc(int integer);
注意,线程函数的声明应在类CMultiThread2Dlg的外部。
在类CMultiThread2Dlg内部添加protected型变量: HANDLE hThread;
DWORD ThreadID;
分别代表线程的句柄和ID。

打开ClassWizard,为编辑框IDC_COUNT添加int型变量m_nCount。在MultiThread2Dlg.cpp文件中添加:void
ThreadFunc(int integer)
{
int i;
for(i=0;i<integer;i++)
{
Beep(200,50);
Sleep(1000);
}
}
双击IDC_START按钮,完成该按钮的消息函数: void CMultiThread2Dlg::OnStart()
{
UpdateData(TRUE);
int integer=m_nCount;
hThread=CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)ThreadFunc,
(VOID*)integer,
0,
&ThreadID);
GetDlgItem(IDC_START)->EnableWindow(FALSE);
WaitForSingleObject(hThread,INFINITE);
GetDlgItem(IDC_START)->EnableWindow(TRUE);
}
顺便说一下WaitForSingleObject函数,其函数原型为:DWORD WaitForSingleObject(HANDLE hHandle,DWORD
dwMilliseconds);
hHandle为要监视的对象(一般为同步对象,也可以是线程)的句柄;
dwMilliseconds为hHandle对象所设置的超时值,单位为毫秒;
当在某一线程中调用该函数时,线程暂时挂起,系统监视hHandle所指向的对象的状态。如果在挂起的dwMilliseconds毫秒内,线程所等待

的对象变为有信号状态,则该函数立即返回;如果超时时间已经到达dwMilliseconds毫秒,但hHandle所指向的对象还没有变成有信号状态,函

数照样返回。参数dwMilliseconds有两个具有特殊意义的值:0和INFINITE。若为0,则该函数立即返回;若为INFINITE,则线程一直被挂起,

直到hHandle所指向的对象变为有信号状态时为止。
本例程调用该函数的作用是按下IDC_START按钮后,一直等到线程返回,再恢复IDC_START按钮正常状态。编译运行该例程并细心体会。
例程3 MultiThread3
传送一个结构体给一个线程函数也是可能的,可以通过传送一个指向结构体的指针参数来完成。先定义一个结构体:
typedef struct
{
int firstArgu,
long secondArgu,

}myType,*pMyType;
创建线程时CreateThread(NULL,0,threadFunc,pMyType,…);
在threadFunc函数内部,可以使用“强制转换”:
int intValue=((pMyType)lpvoid)->firstArgu;
long longValue=((pMyType)lpvoid)->seconddArgu;
……
例程3 MultiThread3将演示如何传送一个指向结构体的指针参数。
建立一个基于对话框的工程MultiThread3,在对话框IDD_MULTITHREAD3_DIALOG中加入一个编辑框IDC_MILLISECOND,一个按钮IDC_START,标题

为“开始”
,一个进度条IDC_PROGRESS1;
打开ClassWizard,为编辑框IDC_MILLISECOND添加int型变量m_nMilliSecond,为进度条IDC_PROGRESS1添加CProgressCtrl型变量

m_ctrlProgress;

在MultiThread3Dlg.h文件中添加一个结构的定义: struct threadInfo
{
UINT nMilliSecond;
CProgressCtrl* pctrlProgress;
};
线程函数的声明: UINT ThreadFunc(LPVOID lpParam);
注意,二者应在类CMultiThread3Dlg的外部。
在类CMultiThread3Dlg内部添加protected型变量: HANDLE hThread;
DWORD ThreadID;
分别代表线程的句柄和ID。
在MultiThread3Dlg.cpp文件中进行如下操作:
定义公共变量 threadInfo Info;
双击按钮IDC_START,添加相应消息处理函数:void CMultiThread3Dlg::OnStart()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
Info.nMilliSecond=m_nMilliSecond;
Info.pctrlProgress=&m_ctrlProgress;
hThread=CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)ThreadFunc,
&Info,
0,
&ThreadID);

}
在函数BOOL CMultiThread3Dlg::OnInitDialog()中添加语句: {
……

// TODO: Add extra initialization here
m_ctrlProgress.SetRange(0,99);
m_nMilliSecond=10;
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
}
添加线程处理函数:UINT ThreadFunc(LPVOID lpParam) {
threadInfo* pInfo=(threadInfo*)lpParam;
for(int i=0;i<100;i++)
{
int nTemp=pInfo->nMilliSecond;
pInfo->pctrlProgress->SetPos(i);
Sleep(nTemp);
}
return 0;
}
顺便补充一点,如果你在void CMultiThread3Dlg::OnStart() 函数中添加语句,编译运行你就会发现进度条不进行刷新,主线程也停止了反应。什么原因呢?这是因为WaitForSingleObject函数等待子线程

(ThreadFunc)结束时,导致了线程死锁。因为WaitForSingleObject函数会将主线程挂起(任何消息都得不到处理),而子线程ThreadFunc正

在设置进度条,一直在等待主线程将刷新消息处理完毕返回才会检测通知事件。这样两个线程都在互相等待,死锁发生了,编程时应注意避免



例程4 MultiThread4
该例程测试在Windows下最多可创建线程的数目。

建立一个基于对话框的工程MultiThread4,在对话框IDD_MULTITHREAD4_DIALOG中加入一个按钮IDC_TEST和一个编辑框IDC_COUNT,按钮标题为

“测试”
, 编辑框属性选中Read-only;
在MultiThread4Dlg.cpp文件中进行如下操作:
添加公共变量volatile BOOL m_bRunFlag=TRUE;
该变量表示是否还能继续创建线程。
添加线程函数:
DWORD WINAPI threadFunc(LPVOID threadNum)
{
while(m_bRunFlag)
{
Sleep(3000);
}
return 0;
}
只要 m_bRunFlag 变量为TRUE,线程一直运行。
双击按钮IDC_TEST,添加其响应消息函数:void CMultiThread4Dlg::OnTest()
{
DWORD threadID;
GetDlgItem(IDC_TEST)->EnableWindow(FALSE);
long nCount=0;
while(m_bRunFlag)
{
if(CreateThread(NULL,0,threadFunc,NULL,0,&threadID)==NULL)
{
m_bRunFlag=FALSE;
break;
}
else
{
nCount++;
}
}
//不断创建线程,直到再不能创建为止
m_nCount=nCount;
UpdateData(FALSE);
Sleep(5000);
//延时5秒,等待所有创建的线程结束
GetDlgItem(IDC_TEST)->EnableWindow(TRUE);
m_bRunFlag=TRUE;
}
五、MFC对多线程编程的支持
MFC中有两类线程,分别称之为工作者线程和用户界面线程。二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息

队列和消息循环。
工作者线程没有消息机制,通常用来执行后台计算和维护任务,如冗长的计算过程,打印机的后台打印等。用户界面线程一般用于处理独

立于其他线程执行之外的用户输入,响应用户及系统所产生的事件和消息等。但对于Win32的API编程而言,这两种线程是没有区别的,它们都

只需线程的启动地址即可启动线程来执行任务。
在MFC中,一般用全局函数AfxBeginThread()来创建并初始化一个线程的运行,该函数有两种重载形式,分别用于创建工作者线程和用户界

面线程。两种重载函数原型和参数分别说明如下:

(1) CWinThread* AfxBeginThread(AFX_THREADPROC pfnThreadProc,
LPVOID pParam,
nPriority=THREAD_PRIORITY_NORMAL,
UINT nStackSize=0,
DWORD dwCreateFlags=0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL);
PfnThreadProc:指向工作者线程的执行函数的指针,线程函数原型必须声明如下: UINT ExecutingFunction(LPVOID
pParam);
请注意,ExecutingFunction()应返回一个UINT类型的值,用以指明该函数结束的原因。一般情况下,返回0表明执行成功。
pParam:传递给线程函数的一个32位参数,执行函数将用某种方式解释该值。它可以是数值,或是指向一个结构的指针,甚至可以被忽略;
nPriority:线程的优先级。如果为0,则线程与其父线程具有相同的优先级;
nStackSize:线程为自己分配堆栈的大小,其单位为字节。如果nStackSize被设为0,则线程的堆栈被设置成与父线程堆栈相同大小;
dwCreateFlags:如果为0,则线程在创建后立刻开始执行。如果为CREATE_SUSPEND,则线程在创建后立刻被挂起;
lpSecurityAttrs:线程的安全属性指针,一般为NULL;
(2) CWinThread* AfxBeginThread(CRuntimeClass* pThreadClass,
int nPriority=THREAD_PRIORITY_NORMAL,
UINT nStackSize=0,
DWORD dwCreateFlags=0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL);

pThreadClass 是指向 CWinThread
的一个导出类的运行时类对象的指针,该导出类定义了被创建的用户界面线程的启动、退出等;其它参数的意义同形式1。使用函数的这个原型

生成的线程也有消息机制,在以后的例子中我们将发现同主线程的机制几乎一样。
下面我们对CWinThread类的数据成员及常用函数进行简要说明。
m_hThread:当前线程的句柄;
m_nThreadID:当前线程的ID;
m_pMainWnd:指向应用程序主窗口的指针
BOOL CWinThread::CreateThread(DWORD dwCreateFlags=0,
UINT nStackSize=0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL);
该函数中的dwCreateFlags、nStackSize、lpSecurityAttrs参数和API函数CreateThread中的对应参数有相同含义,该函数执行成功,返回

非0值,否则返回0。
一般情况下,调用AfxBeginThread()来一次性地创建并启动一个线程,但是也可以通过两步法来创建线程:首先创建CWinThread类的一个

对象,然后调用该对象的成员函数CreateThread()来启动该线程。

virtual BOOL CWinThread::InitInstance();
重载该函数以控制用户界面线程实例的初始化。初始化成功则返回非0值,否则返回0。用户界面线程经常重载该函数,工作者线程一般不

使用InitInstance()。
virtual int CWinThread::ExitInstance();
在线程终结前重载该函数进行一些必要的清理工作。该函数返回线程的退出码,0表示执行成功,非0值用来标识各种错误。同

InitInstance()成员函数一样,该函数也只适用于用户界面线程。
六、MFC多线程编程实例
在Visual C++
6.0编程环境中,我们既可以编写C风格的32位Win32应用程序,也可以利用MFC类库编写C++风格的应用程序,二者各有其优缺点。基于Win32的

应用程序执行代码小巧,运行效率高,但要求程序员编写的代码较多,且需要管理系统提供给程序的所有资源;而基于MFC类库的应用程序可以

快速建立起应用程序,类库为程序员提供了大量的封装类,而且Developer
Studio为程序员提供了一些工具来管理用户源程序,其缺点是类库代码很庞大。由于使用类库所带来的快速、简捷和功能强大等优越性,因此

除非有特殊的需要,否则Visual
C++推荐使用MFC类库进行程序开发。
我们知道,MFC中的线程分为两种:用户界面线程和工作者线程。我们将分别举例说明。
用 MFC 类库编程实现工作者线程

‘玖’ 自学《window程序设计》需要什么基础啊例如什么基础课程之类的!

1 0001 4423 马克思主义哲学原理 3 哲学(0006) 一代三
2 0002 4424 DXP理论概论 3
3 0003 4425 法律基础与思想道德修养 2
4 0012 4405 英语(一) 7 英语(一)
5 0022 4403 高等数学(工专) 7 高等数学(工专)
6 2198 4402 线性代数 3 线性代数
7 2314 4420 模拟电路与数字电路 6 电子线路与数字逻辑
2315 模拟电路与数字电路(实践) 2
8 2316 4426 计算机应用技术 2 计算引论
2317 计算机应用技术(实践) 3
9 2321 4411 汇编语言程序设计 3 汇编语言程序设计
2322 汇编语言程序设计(实践) 1
10 0342 4412 高级语言程序设计 3 FORTRAN语言
0343 高级语言程序设计(实践) 1
11 2142 4413 数据结构导论 4 数据结构
12 2318 4409 *计算机组成原理 4 计算机组成原理
13 2319 44121 *微型计算机及接口技术 2 微型计算机及应用
2320 *微型计算机及接口技术(实践) 2
14 2323 4414 *操作系统概论 4 操作系统
15 2120 4415 *数据库及应用 3 数据库概论
2121 *数据库及应用(实践) 1
16 2141 4422 *计算机网络技术 4 电工电子学或普通物理
计算机操作技术或计算方法
17 4427 实践考核:综合实验(10)

首 页| 自考简介 | 考试机构 | 考试计划 | 考试动态 | 学习园地 | 政策查询 | 自考期刊 | 教材信息 | 社考专栏 | 下载中心 | 自考论坛

本 科 专 业
专 科 专 业
开考体制改革试点专业
命题动态 自学考试
国家学历文凭考试 非学历证书考试
全国计算机等级考试 全国英语等级考试
NIT考试 全国少儿计算机考试
“两学”考试 全国外语翻译证书考试
剑桥办公管理国际证书考试 剑桥少儿英语等级考试
剑桥英语五级证书考试 社会艺术水平考级
全国大学英语四、六级考试(CET) 中国市场营销资格证书考试
学习方法
考试技巧
样题选登
助学单位
有关政策与法规
自学考试暂行条例
自学考试有关规定
现行报考收费文件
福建省自学考试奖励基金会
助学文件查询
2005年《福建自学考试》
2004年《福建自学考试》
2003年《福建自学考试》
2002年《福建自学考试》
2001年《福建自学考试》
购买教材须知 自学考试教材
中英合作教材 全国公共英语等级考试(PETS)教材
全国计算机等级考试(NCRE)教材 全国计算机应用技术证书考试(NIT)教材
全国少儿计算机考试(少儿NIT)教材 两学教育考试教材
全国外语翻译证书考试(NAETI)教材 英语专业教材配套VCD、磁带
2004年《活页文丛》目录 教材相关新闻
全国计算机等级考试(NCRE) 全国英语等级考试(PETS)
全国计算机应用技术证书考试(NIT) 全国外语翻译证书考试(NAETI)
“两学”考试 剑桥办公管理国际证书考试
全国剑桥少儿英语等级考试 剑桥英语五级证书考试
社会艺术水平考级 全国少儿计算机考试
全国大学英语四、六级考试(CET) 中国市场营销资格证书考试
全国高等学校英语应用能力考试
相关文档
全省自考工作会暨表彰大会材料
考务考籍相关软件
自学考试基金会表格

你的位置:首页>>考试计划>>开考体制改革试点专业

计算机软件专业(本科)考试计划

--------------------------------------------------------------------------------

来源:福建自考办
2006-02-23

高等教育自学考试计算机软件专业(本科)考试计划

专业代码:080718(基础科段)、080719(本科段)

主考学校:福建农林大学

一.指导思想

高等教育自学考试是我国高等教育基本制度之一,是以高等教育学历考试为主的国家考试,是个人自学、社会助学、国家考试相结合的高等教育形式,是我国高等教育体系的重要组成部分。

高等教育自学考试计算机软件专业(本科)是为满足软件产业迅速发展需要而设置的;同时,根据高等教育自学考试的特点,具有较强的针对性和实用性,注重考核应考者对本专业的基本理论、基础知识和基本技能的掌握程度以及运用所学知识分析和解决问题的能力。

二.学历层次和规格

本专业分专科和本科两种学历,在总体上与全日制普通高校相近专业同等学历的水平相一致。

本专业考试计划为衔接式计划,整个计划分为基础科段和本科段两个既相对独立又互相衔接的阶段,依据不同层次考生采取不同的培养模式,形成多模式的应用型软件人才培养体系。凡通过本计划基础科段规定的15门课程考试,成绩合格,并通过相应课程的实践考核,累计达到80学分,思想品德经鉴定符合要求者,发给专科毕业证书。凡继续参加本计划本科段规定的12门课程考试,成绩合格,并通过相应课程的实践考核,完成毕业设计并合格,思想品德经鉴定符合要求者,发给本科毕业证书。

凡获得本科毕业证书,其学业水平达到了国家规定的学位标准,按照《中华人民共和国高等教育法》第二十二条和《中华人民共和国学位条例》的规定,由主考学校授予学士学位。

三.专业培养目标和基本要求

高等教育自学考试计算机软件专业(本科)培养德、智、体全面发展的,具有坚实的计算机实际应用技能与方法,具有良好的科学素质、创新精神、实践能力和国际竞争能力、适应国内外软件产业市场需求的国际型、通用型、实用型的软件高级专门人才。本专业要求应考者努力学习马克思列宁主义、毛泽东思想、邓小平理论,树立爱国主义、集体主义和社会主义思想,遵守法律、法规,具有良好的思想品德。要求掌握计算机科学方面的基本理论与方法,掌握计算机软件主流技术、软件开发方法与软件工程、软件项目工程组织与管理;有良好的外语运用技能。可以攻读计算机科学和相近学科的有关研究方向硕士学位。

四.考试课程与学分

(1)基础科段(C080718)

序号
课程代码
课程名称
学分

1*
0001
马克思主义哲学原理
3

2*
0002
邓小平理论概论
3

3*
0003
法律基础与思想道德修养
2

4*
0011
大学语文(本)
6

5*
0023
高等数学(工本)
10

6*
0015
英语(二)
14

7*
2198
线性代数
3

8*
2316
计算机应用技术
2

2317
计算机应用技术(实践)
3

9*
0342
高级语言程序设计(一)
3

0343
高级语言程序设计(一)(实践)
1

10
7011
数字逻辑电路
5

7012
数字逻辑电路(实践)
2

11*
2318
计算机组成原理
4

12
7013
算法与数据结构
4

7014
算法与数据结构(实践)
1

13*
2326
操作系统
4

2327
操作系统(实践)
1

14*
2336
数据库原理
4

2337
数据库原理(实践)
1

15*
0896
电子商务概论
4

0897
电子商务概论(实践)
2

总学分

82

(2)本科段(C080719)

序号
课程代码
课程名称
学分
备注

1*
0004
毛泽东思想概论
2

2*
0005
马克思主义政治经济学原理
3

3*
2197
概率论与数理统计(二)
3

4
7015
计算机专业英语
6

5*
2324
离散数学
4

6*
2339
计算机网络与通信
6

7
7016
编译原理
5

8*
2333
软件工程
3

2334
软件工程(实践)
1

9*
3142
互联网技术及应用
4

3143
互联网技术及应用(实践)
1

10
7017
面向网络编程技术
4

7018
面向网络编程技术(实践)
1

11
7019
分布式数据库
4

7020
分布式数据库(实践)
1

12
7021
软件能力成熟度模型(CMM)
4
过程考核

6998
毕业设计

不计学分

总学分
52

1*
0023
高等数学(工本)
10









2
7013
算法与数据结构
4

7014
算法与数据结构(实践)
1

3*
2326
操作系统
4

2327
操作系统(实践)
1

4*
2318
计算机组成原理
4

5*
2336
数据库原理
4

2337
数据库原理(实践)
1

说明:

1.序号后加“*”号为全国统考课程。

2.年龄在40岁以上的考生可申请免考英语(二),但必须加考三门课程,其学分不少于14学分。三门课程为:工程经济(4学分)(课程代码2194)、网络操作系统(5学分)(课程代码2335)、局域网技术与组网工程(5学分)(课程代码3141)。

3.为鼓励考生参加国际国内认证,凡获得SUN公司的JAVA认证可免考“面向网络编程技术”课程;凡获得Oracle公司的Oracle认证,可免考“分布式数据库”课程等。

4.报考本科段的条件

(1)学完本计划基础科段的考生可直接报考本专业本科段。

(2)计算机类各专业(非本专业基础科段)专科毕业生报考本专业须加考1一门课程

(3)电工电子信息类非计算机类各专业专科及专科以上学历层次的毕业生报考本专业,须加考1、2、3三门课程。

(4)理工类非电工电子信息类专业专科及专科以上学历层次的毕业生报考本专业,须加考1、2、3、4四门课程。

(5)非理工科类各专业专科及专科以上学历层次的毕业生报考本专业,须加考1、2、3、4、5五门课程。

五.课程说明和自学教材

1.马克思主义哲学原理(课程说明略)

自学教材:《马克思主义哲学原理》赵家祥编,经济科学出版社

2.邓小平理论概论(课程说明略)

自学教材:《邓小平理论概论》钱淦荣编,中国财政经济出版社

3.法律基础与思想道德修养(课程说明略)

自学教材:《法律基础与思想道德修养》,巩献田编,高等教育出版社

4.毛泽东思想概论(课程说明略)

自学教材:《毛泽东思想概论》罗正楷主编,武汉大学出版社

5.马克思主义政治经济学原理(课程说明略)

自学教材:《马克思主义政治经济学原理》卫兴华主编,武汉大学出版社

6.大学语文(本)

本课程为本专业的一门公共课,是为了提高自学应考者语言文化素养和公共文化基础知识而设置的公共课程。内容包括范文选读以及与之相关的语言知识和文学知识。

通过该课程的学习,旨在使应考者对一般文言文具有初步阅读能力,对一般说明、议论、记叙文章具有较强的理解、分析能力,对文学艺术作品具有初步分析、鉴赏能力。该课程的考核应注重知识的初步应用能力。

自学教材:《大学语文》徐中玉主编,华东师范大学出版社

7.英语(二)

本课程为本专业的一门公共课。本课程的目的是使应考者掌握4000个单词(含中学阶段1600个单词)、一定量的习语和系统的语法知识,具有较强的阅读能力和一定的英译汉能力以及初步的听、说、写和汉译英的能力,使其能以英语为工具,获取专业所需要的信息,并为进一步提高英语水平打下较好的基础。

应考者在学完本课程后,应能借助词典独立阅读与后期课文难度相当的一般性资料,并能译成汉语,理解基本正确,译文基本通顺。

自学教材:《大学英语自学教程》(上、下册)高远主编,高等教育出版社

8.高等数学(工本)

本课程为本专业的一门公共课。通过学习,要求应考者系统地获得一元函数的微积分学、多元函数微积分学(包括向量代数与空间解析几何)、常微分方程、级数的基本知识、理论和方法。要求应考者掌握各有关内容的基本概念、基本理论和基本方法,具有比较熟练地运用能力和分析能力、空间想象能力及抽象数学模型的初步能力,为学习后续课程和进一步扩大数学知识奠定必要的基础。

自学教材:《高等数学》(上、下册)陈庆乐主编,西安交通大学出版社

9.线性代数

本课程为本专业的一门公共课。其内容包括:行列式,矩阵及其运算,向量的线性相关矩阵,线性方程组、特征值问题与实二次型。

通过本课程的学习,使应考者掌握行列式的定义,性质;熟练运用矩阵的运算法则;熟练掌握线性方程组解的结构及其判别法则,掌握特征值的重要概念。

自学教材:《工程数学(线性代数)》魏战线主编,辽宁大学出版社

10.数字逻辑电路

本课程为本专业的一门主要专业基础课。内容包括:数字电子技术概述、逻辑代数、集成逻辑门、组合逻辑电路、时序逻辑电路、存储器、脉冲信号的产生和变换电路、数模和模数转换器、中小规模的逻辑电路设计。

通过本课程的学习,使应考者掌握一些数字逻辑电路基本理论、概念、方法及应用,具有中小规模逻辑电路设计初步能力。

自学教材:《数字集成电路基础》皇甫正贤编着,南京大学出版社

11.计算机应用技术

本课程为本专业的一门专业基础课。内容包括:计算机应用基础知识、DOS、WINDOWS操作系统简介、中文WINDOW95/98操作系统的使用,汉字输入/输出方法综述、字处理软件WORD97与表格处理软件EXCEL97、网络初步知识。

通过本课程学习,使应考者具有微机应用、文字编辑表格生成的能力。

自学教材:《计算机应用技术》张宁主编,经济科学出版社

12.高级语言程序设计

本课程为本专业的主要一门专业基础课之一。内容包括:C语言程序结构、基本数据类型和运算、各类语句、构造数据类型(数组结构、联合、枚举)和应用,指针、函数、编译预处理、文件处理、C语言程序设计和调试。

通过本课程学习,使应考者掌握C语言及使用C语言编程的知识,具有用C语言描述、求解问题的基本能力。

自学教材:《高级语言程序设计》迟成文主编,经济科学出版社

13.计算机组成原理

本课程为本专业的主要一门专业基础课之一。内容包括:计算机系统的基本概念、运算组织、存储器组织、导址技术和指令系统、整机结构、控制器的设计、输入输出和接口等。

通过本课程学习,使应考者掌握计算机基本组成结构及各部件的工作原理和逻辑实现。

自学教材:《计算机组成原理》胡越明主编,经济科学出版社

14.算法与数据结构

本课程为本专业的一门专业基础课。课程内容有:算法与数据结构的基本概念,包括算法的时间、空间复杂性和抽象数据类型;基于序列的抽象数据类型表、栈、队列、串;反映层次关系的抽象数据类型树;在实际应用中常用的排序与选择算法;非线性结构图及图的算法;表示集合的抽象数据类型,包括字典、优先队列和并查集等。

通过本课程的学习,使应考者在掌握基础知识的同时,加深理解“算法”与“数据结构”的紧密关系,学会分析研究实际问题的特点,选择适当的数据结构和存储结构,设计有效的求解算法;通过实践训练,强化学生运用基本数据结构进行复杂程序设计的训练过程,提高利用计算机解决实际问题的实践技能。

自学教材:《数据结构??用C语言描述》宁正元主编,水电出版社

15.数据库原理

本课程为本专业的一门专业基础课。本课程内容为:数据库概论、关系数据模型、关系运算理论、SQL语言、关系数据库的规范化,数据库设计的全过程、数据库的保护、数据库管理系统的结构,以及分布式数据库面向对象的数据库等数据库新技术的介绍。

通过本课程的学习,使应考者掌握数据库的基本原理和技术,能应用现有数据库管理系统,掌握数据库设计和数据库系统的开发方法。

自学教材:《数据库原理》丁宝康主编,经济科学出版社

16.操作系统

本课程为本专业的一门专业基础课。课程内容为:操作系统的典型算法和结构、作业管理、进程管理、存储管理、设备管理、文件管理、操作系统结构设计以及UNIX操作系统介绍。

通过本课程的学习,使应考者掌握操作系统的基本结构、设计原理及实现方法,了解它与硬件和其它系统软件的关系,能使用和分析常见的操作系统。

自学教材:《操作系统》谭耀明主编,中国人民大学出版社

17.概率论与数理统计

本课程为本专业的一门公共课。是研究随机现象统计规律的一门数学课。本课程概率论部分包括:随机事件及其概率、随机变量、多维随机变量和随机变量的数字特征等内容;数理统计部分包括抽样分布、参数估计、假设检验、方差分析、回归分析和正交试验设计等内容。

通过本课程的学习,要求应考者理解概率论的基本概念,熟悉随机事件及其概率的重要性质,熟悉随机变量的常用分布,并会进行相应的计算。掌握数理统计中有关参数估计和假设检验的方法,了解方差分析、回归分析和正交试验设计。

自学教材:《工程数学(概率论与数理统计)》范金城主编,辽宁大学出版社

18.离散数学

本课程为本专业的一门专业基础课。课程内容为:命题逻辑和一阶谓词逻辑的基本概念和基本演算;集合的概念和运算、二元关系和函数;代数运算和代数系统的基本性质、半群和群、队和域、格和布尔代数;图的基本概念、树、欧拉图和哈密顿图、平面图、图着色、赋权图、二部图等。

通过本课程的学习,使应考者有抽象思维和逻辑推理能力,掌握计算机科学技术常用的离散数学中的概念、性质和运算。

自学教材:《离散数学》左孝凌等编,上海科技出版社

19.计算机专业英语

本课程为专业的一门专业基础课。课程内容有:计算机专业词汇,包括一般的单词在计算机科学中的不同的意义,以及各种缩写词(操作系统、与计算机有关的组织、各种应用软件、计算机的各种部件等);操作过程中出现“出错信息”理解,以及对解决问题的解释;通过查阅字典完成对一些英语版应用软件中README、HELP文件的阅读、理解,从而解决在将来的日常应用中使用英语版应用软件的能力等。

通过本课程的学习,使应考者能熟练阅读计算机外文资料,熟练理解操作过程中出现的“出错信息”,提高计算机软件编程能力。

自学教材:软件工程英语 Philip Lew 孙伟 清华大学出版社

20.互联网及其应用

本课程为本专业的一门应用性和实践性都很强的专业课。课程内容包括:Internet和Intranet的概念和基本原理、连接方式和接口、IP地址、上网步骤、网络服务、E-Mail、WWW及其主页、电子新闻、远程登录查询、DNS域名服务、BBS电子布告、应用工具等。

自学教材:《互联网及其应用》袁宝宗主编,吉林大学出版社

21.电子商务概论

本课程为本专业的一门专业课。课程内容有:电子商务的基本知识及电子商务所涉及的相关问题,并了解目前国内外企业对这些问题的人认识与解决方式;客户关系管理(CRM);供应链管理(SCM);财务实时处理(STP);网络整合(WI);合作与兼并;知识管理(KM);企业资源策划(ERP)和企业电子商务战略管理与风险管理。

通过课程的学习,使应考者掌握电子商务的基本知识,着重培养如何进行电子商务、如何进行企业的电子规划等。通过课程教学,应着重培养学生具备以下两方面的良好素质。一是针对现有电子商务系统设计与开发中出现的复杂问题,善于综合运用所学基本理论和知识对具体问题提出解决的方案;二是培养网络经济时代企业经理人的电子商务的基本素质。

自学教材:《电子商务学概论》陈国龙等编着,厦门大学出版社

22.软件工程

本课程为本专业的一门专业课。课程内容包括:软件工程的基本概念、可行性研究与计划、需求分析和规格说明方法、设计方法、编程方法、检验和测试方法、维护方法,面向对象的软件开发方法、软件工具和环境等。

通过本课程的学习,使应考者掌握软件工程和有关概念和和各阶段的主要技术、方法与工具、具备组织和从事软件开发的基本能力。

自学教材:《软件工程》陆丽娜编,经济科学出版社

23.计算机网络与通信

本课程为本专业的一门专业基础课。课程内容:数据通信技术、包括数据传输原理、通信交换技术、通信规程、差错控制等;计算机网络体系结构、QSI中的物理层、数据链路层、网络层、传输层及高层协议;计算机局域网、网络互连、因特网的实用技术与应用等。

通过本课程的学习,使应考者了解简化的ISO/OSI参考模型,掌握计算机网络基本原理和概念,熟悉计算机网络典型技术与协议,具备适应网络发展的能力。

自学教材:《计算机网络与通信》冯博琴主编,经济科学出版社

24.面向网络编程技术

本课程为本专业的一门专业课。课程内容有:Java语言基本特点、主要内容和结构,抽象窗口工具箱的概念,半编译和虚拟机的概念及应用;一般Java开发环境的工作方式;Java applet的开发和设计方法;Java语言的语法规定、数据类型和面向对象的程序设计方式,Symmantec Java 图形界面设计方式和 V J++的常用控件;Java接口和包的概念、构造和使用包的方法,异常抛出机制、异常处理机制;Java的输入输出方式,网络环境编程、网址的处理、统一资源定位器(URL)的概念和TCP/IP Socket的实现。

通过本课程的学习,培养应考者掌握运用Java先进的语言机制、构造问题的模型建立解决问题方案的能力。培养应考者运用面向对象程序设计、多线程程序设计、applet设计及网络环境编程的能力。通过课程的学习,主要提高应考者以下两方面的素质,其一,学会从系统的角度分析问题,建立问题解决方案;其二,理解跨平台语言的本质和机理,理解Java虚拟机的机制。

自学教材:《Java与面向对象程序设计教程》李金铭编着,清华大学出版社

25.编译原理

本课程为本专业的一门专业课。课程内容有:有限自动机和形式语言理论的基本概念;语法分析各种技术;语义生成和优化技术;自动生成工具的使用方法。

通过课程的学习,培养应考者抽象思维和逻辑推理能力;培养应考者利用自动机理论和形式语言理论解决实际问题的能力;具备应用编译技术和方法构造编译系统和其它应用软件的能力。通过课程学习,将使应考者在以下方面得到锻炼和提高:1)对程序设计语言使用将有更深入的认识和了解;2)在抽象思维和形式推理的能力方面得到良好的锻炼。

自学教材:《编译原理》康慕宁编着,西北工大出版社

26.分布式数据库

本课程为本专业的一门专业课。课程内容有:分布式数据库基本概念;分布式数据库系统体系结构;数据分布;分布式查询处理;分布式事务管理;分布式并发控制与恢复;分布式完整性与安全性,以及以oracle为示例,展开对分布式数据库原理和开发的介绍。

随着用户对数据库应用需求的不断发展,数据库技术经历了如下的几个变迁:从集中式→分布式,从C/S→B/S,从关系数据库→面向对象数据库,等等。数据库技术面临着前所未有的挑战和机遇。在众多的数据库新技术中,分布式数据库系统是研究得比较透彻、技术上比较成熟的一门计算机前沿学科。因此,仅仅学习和掌握《数据库系统原理》,对计算机本科生在今后实际工作中开展数据库新技术的研究,是远远不够的。因此,必须通过本课程的学习,使学生掌握分布式数据库系统的基本原理、基本概念,并初步具备分布式数据库应用系统的开发经验,才能培养出的计算机应用(特别是数据库应用)高级专业人才在计算机应用领域中处于先进行列。

自学教材:自编,出版社待定

参考教材:《分布式数据库》郑振楣等编着,科学出版社

《Oracle 9i中文版基础教程》张曜等编着,清华大学出版社

27.软件能力成熟度模型(CMM)

本课程为本专业的一门专业课。课程内容有:CMM的基本概念,总体框架;各个成熟度等级相关的关键过程的目标和关键实践;国际上有关软件成熟度模型的新进展,重点介绍集成的能力成熟度模型CMMI;个体软件过程PSP;软件过程评估方法的比较。

软件能力成熟度模型被国际软件界公认为是软件工程学的一项重大成果。通过课程的学习,培养应考者科学地评价软件开发单位的软件能力成熟度等级,帮助软件开发单位进行自检,了解自已的强项和弱项,从而不断完善单位的软件开发过程,确保软件质量,提高软件开发效率。

自学教材:《软件能力成熟度模型》何新贵等编着,清华大学出版社
另外,团IDC网上有许多产品团购,便宜有口碑

阅读全文

与window多线程编程相关的资料

热点内容
安卓手机浏览器怎么扫二维码 浏览:715
通达信成本均线源码 浏览:614
可以下载的解压音频 浏览:564
海贼王怎么换服务器 浏览:318
计算机上的共享文件夹映射 浏览:940
荣耀安装包在文件夹哪里 浏览:195
机票php源码 浏览:231
linux共享mac 浏览:922
中国没有国外的服务器地址 浏览:759
为什么退款服务器连接错误 浏览:557
android短信存储位置 浏览:970
unix网络编程卷4 浏览:808
找靓机app下单什么时候发货 浏览:413
android一个应用两个进程 浏览:803
linux硬盘复制 浏览:808
php图片服务器搭建 浏览:801
下载压缩文件怎么打开 浏览:194
新建文件夹叫什么名字 浏览:567
windows20的开机命令 浏览:335
微信一般在电脑的那个文件夹 浏览:511