Windows进程和线程.docx

上传人:b****7 文档编号:23933213 上传时间:2023-05-22 格式:DOCX 页数:19 大小:201.42KB
下载 相关 举报
Windows进程和线程.docx_第1页
第1页 / 共19页
Windows进程和线程.docx_第2页
第2页 / 共19页
Windows进程和线程.docx_第3页
第3页 / 共19页
Windows进程和线程.docx_第4页
第4页 / 共19页
Windows进程和线程.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

Windows进程和线程.docx

《Windows进程和线程.docx》由会员分享,可在线阅读,更多相关《Windows进程和线程.docx(19页珍藏版)》请在冰豆网上搜索。

Windows进程和线程.docx

Windows进程和线程

Windows进程和线程

1进程

1.1特点

每个进程都有自己的ID号

每个进程都有自己的地址空间,进程之间无法访问对方的地址。

每个进程都有自己的安全属性。

每个进程当中至少包含一个线程。

1.2进程环境信息

也称:

进程上下文。

1.2.1获取和释放环境信息

获取GetEnvironmentStrings

释放FreeEnvironmentStrings

1.2.2获取和设置环境变量

获取环境变量

设置环境变量

1.2.3进程的信息

1进程ID

GetCurrentProcessId

2进程句柄

GetCurrentProcess返回程序的伪句柄(-1),可以使用该句柄访问该进程的所有操作。

1.2.4进程的使用

1创建进程

WinExec-早期16位操作系统

ShellExecute-Shell操作

CreateProcess-目前最多使用

2退出线程

只能结束本进程参数没有实际意义

能结束其他及自身线程退出码没有实际意义

3通过进程ID获取进程句柄

OpenProcess

4关闭进程句柄

CloseHandle

作用:

把进程的句柄置为-1

5进程间的等候

WaitForSingleObject

等候可等候的句柄的信号。

阻塞函数,等候句柄的信号,只在句柄有信号或超出等候时间,才会结束等候。

备注

进程地址空间:

底层驱动的进程空间:

4G,驱动可任意访问上层应用的地址空间

2线程

Windows线程是可以执行的代码的实例。

系统是以线程为单位调度程序。

一个程序当中可以有多个线程,实现多任务的处理。

Windows线程的特点:

1线程都具有一个ID

2线程具有自己的安全属性

3每个线程都具有自己的栈内存(默认1M)

4每个线程都有自己的寄存器信息

进程多任务和线程多任务:

进程多任务是每个进程都使用私有地址空间,

线程多任务是进程内的多个线程使用同一个地址空间

线程的调度:

将CPU的执行时间划分成时间片,依次根据时间片执行不同的线程。

线程轮询:

线程A->线程B->线程A......

2.1线程的使用

1定义线程处理函数

2创建线程

返回线程句柄,线程句柄是可等候句柄

dwCreateionFlags方式只有两种:

0,立即执行;CREATE_SUSPENDED,使用ResumeThread函数唤醒

3结束线程

ExitThread结束本线程

TerminateThread结束制定线程

4关闭线程句柄

CloseHandle并不是关闭线程,而是关闭线程句柄

.

5线程的挂起和执行

挂起

SuspendThread

执行

ResumeThread

6线程的信息

GetCurrentThreadId-获取当前线程的ID

GetCurrentThread-获取当前线程的句柄

打开指定ID的线程,获取其句柄

OpenThread

2.2多线程的问题

线程A->线程B->线程A。

分析代码:

创建线程函数

线程处理函数

现象

分析:

当线程A执行printf输出时,如果线程A的执行时间结束,系统会将线程A的相关信息(栈、寄存器)压栈保护,同时将线程B相关信息恢复,然后执行线程B,线程B继续输出字符。

由于线程A正输出字符,线程B会继续输出,画面字符会产生混乱。

2.3线程同步技术

原子锁

临界区(段)

互斥

事件

信号量

可等候定时器

共六种线程同步技术,其中加锁的是:

原子锁、临界区(段)、互斥;剩下的三个不是加锁。

总结:

2.3.1等候函数

WaitForSingleObject-等候单个

WaitForMultipleObjects-等候多个

可等候多个句柄,但是必须是可等候句柄

bWaitAll-等候方式

TRUE-表示所有句柄都有信号,才结束等候

FASLE-表示句柄中只要有1个有信号,就结束等候。

2.4原子锁

例子:

循环一亿次,最终结果,g_nValue不是两亿

当线程A执行g_nValue1++时,如果线程切换时间

正好是在线程A将值保存到g_nValue1之前,

线程B继续执行g_nValue1++,那么当线程A再次被切换回来之后,会将原来线程A保存的值保存到g_nValue1上,

线程B进行的加法操作被覆盖。

g_nValue1++的汇编码

00401063movecx,dwordptr[g_nValue(00427c48)]

00401069addecx,1

0040106Cmovdwordptr[g_nValue(00427c48)],ecx

其伪代码如下:

ecx=g_nValue;

ecx=ecx+1;

g_nValue=ecx;

原子锁的使用

原子锁–对单条指令的操作。

InterlockedIncrement

InterlockedDecrement

InterlockedCompareExchange

InterlockedExchange

原子锁实现:

直接对数据所在的内存操作,并且在任何一个瞬间只能有一个线程访问。

原子锁是加锁技术中效率最高的。

2.5临界区

原子锁能实现的操作,临界区完全可以实现;临界区能实现的,原子锁不一定能实现。

相关问题

printf输出混乱,多线程情况下同时使用一段代码。

临界区可以锁定一段代码,防止多个线程同时使用该段代码

2.5.1使用

1初始化一个临界区

InitializeCriticalSection

2进入临界区

EnterCriticalSection添加到被锁定的代码之前

3离开临界区

添加到被锁定的代码之后

4删除临界区

临界区和原子锁相比,原子锁的效率比较高

2.6互斥

Mutex

相关的问题

多线程下代码或资源的共享使用。

2.6.1互斥的使用

1创建互斥

2等候互斥

WaitForSinglObject。

等待句柄填互斥句柄

3释放互斥

4关闭互斥句柄

CloseHandle

临界区和互斥的区别

临界区-用户态,执行效率高,只能在同一个进程中使用。

互斥-内核态,执行效率低,可以通过命名的方式跨进程使用。

注意:

操作系统进入win7之后,互斥已经用在内核,上层应用使用临界区

2.7事件

程序之间的通知的问题。

注意:

事件的死锁。

例如:

Thread1:

WaitFor(事件1)

SetEvent(事件2)

Thread2:

WaitFor(事件2)

SetEvent(事件1)

如此,形成死锁

2.7.1事件的使用

1创建事件CreateEvent

bManualReset事件的复位方式,TRUE手动,FALSE自动

bInitialState事件初始状态,TRUE有信号,FALSE无信号

2等候事件

WaitForSingleObject

WaitForMultipleObjects不可等待一个事件

3触发事件SetEventResetEvent

将事件设置成有信号状态

将事件设置成无信号状态

当bManualReset为FALSE时,WaitForSingleObject伪代码如下:

WaitForSingleObject

……

根据g_hEvent找到内存,可以获知事件复位方式

if(事件是自动复位)

ResetEvent…

……

4关闭事件

ColseHnadle

2.8信号量

相关的问题

类似于事件,解决通知的相关问题。

但是可以提供一个计数器,可以设置次数。

2.8.1信号量的使用

1创建信号量

CreateSemaphore

2等候信号量

WaitFor...

每等候通过一次,信号量的信号减1,直到为0阻塞

3给信号量重新指定一个计数值

ReleaseSemaphore

4关闭信号量句柄

CloseHandle

2.9可等候计时器

解决线程之间的通知问题,精度以100纳秒为单位,只适用于第一次启动时间,以后间隔事件仍然以毫秒为单位。

2.9.1可等候计时器的使用

1创建可等候定时器

CreateWaitableTimer

bManualReset复位方式

返回可等候定时器句柄

只要定时器时间没到,可等候定时器句柄无信号;可等候定时器有信号只是一瞬间。

2配置可等候定时器

SetWaitTimer

pDueTime:

第一次启动时间正数-绝对时间(年月日时分秒)

负数–相对时间(例如:

-100,000,000=10秒以后启动)

lPeriod:

间隔时间以毫秒为单位,如果参数为0,定时器只执行一次(执行启动那次)。

pfnCompletionRoutine:

APC回调函数,可以为空

lpArgToCompletionRoutine:

APC回调函数的参数

fResume:

待机处理标识TRUE:

解除待机,唤醒机器

FALSE:

放弃通知。

3等候。

WaitForSingleObject

WaitForMultipleObjects

……

4关闭信号量句柄

CloseHandle

2.9.2注意

可等候定时器只适用于NT5.0及其以上版本。

2.10练习

要求:

1按键盘数字键输出相应行数的*,比如按5,输出5行*

2按e或者按E,程序自然退出(子线程结束,主线程return)

提示:

事件和信号量配合实现

两个子线程

代码:

#include

#include

#include

HANDLEg_hEvent=0;

HANDLEg_hSem=0;

DWORDCALLBACKPrintProc(LPVOIDwParam)

{

HANDLEnHandle[2]={0};

nHandle[0]=g_hSem;

nHandle[1]=g_hEvent;

while

(1)

{

//只要有一个句柄有信号,就返回

DWORDnIndex=WaitForMultipleObjects(2,nHandle,FALSE,INFINITE);

if(nIndex==WAIT_OBJECT_0)

{

printf("********\n");

}

else

{

return0;

}

}

return0;

}

DWORDCALLBACKCtrlProc(LPVOIDwParam)

{

while

(1)

{

charcInput=getch();

if(cInput=='e'||cInput=='E')

{

//结束另外一个子线程

SetEvent(g_hEvent);

return0;

}

intnCount=cInput-'0';

if(nCount<10&&nCount>0)

{

ReleaseSemaphore(g_hSem,nCount,NULL);

}

}

return0;

}

intmain()

{

//事件

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

//信号量

g_hSem=CreateSemaphore(NULL,0,10,NULL);

DWORDnID=0;

HANDLEhThread[2]={0};

hThread[0]=CreateThread(NULL,0,PrintProc,NULL,0,&nID);

hThread[1]=CreateThread(NULL,0,CtrlProc,NULL,0,&nID);

WaitForMultipleObjects(2,hThread,TRUE,INFINITE);

printf("WaitOver\n");

CloseHandle(g_hEvent);

CloseHandle(g_hSem);

CloseHandle(hThread[0]);

CloseHandle(hThread[1]);

return0;

}

3总结

1可等候句柄

进程句柄/线程句柄/事件句柄/互斥句柄/信号量/可等候计时器

WIN32到此为止~

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 军事

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1