Windows进程
 
 1 Windows进程
    进程是一个容器,包括了一个应用程序实例的各种资源。Windows多任务的操作系统,因此能够同一时候运行多个进程。
    
  2 Windows进程的一些特点
    2.1 进程中包括了运行代码等资源。
    2.2 进程都具有私有的地址空间。
    2.3 每一个进程都有一个ID,标识进程。
    2.4 每一个进程都有自己的安全属性
    2.5 至少要包括一个能够运行的线程。
    
二 进程的环境

1 环境信息的获取
    获取:
    LPVOID GetEnvironmentStrings(VOID)
    返回值是获取到的全部环境信息
    释放:

    BOOL FreeEnvironmentStrings(
LPTSTR lpszEnvironmentBlock )

2 环境变量的获取和设置
    获取:

     DWORD GetEnvironmentVariable(
LPCTSTR lpName, //变量名称
LPTSTR lpBuffer, //数据BUFF
DWORD nSize //BUFF的长度
);

返回值是获取到的字符串的长度
    设置:

  BOOL SetEnvironmentVariable(
LPCTSTR lpName, //变量名称
LPCTSTR lpValue //变量的值
);

三 进程的信息
   1 进程ID和句柄
     GetCurrentProcessID 获取进程的ID
     GetCurrentProcess 获取进程的句柄,
         返回值为-1,是当前进程的伪句柄,永远是-1.假设想获取当前进程的实际句柄须要使用OpenProcess函数.
   2 打开进程

     HANDLE OpenProcess(
DWORD dwDesiredAccess, //訪问模式
BOOL bInheritHandle, //继承标识
DWORD dwProcessId //进程ID
);

返回进程的句柄
   3 获取进程的所使用的全部模块(EXE或DLL)
     使用PSAPI函数.

      BOOL EnumProcessModules(
HANDLE hProcess,//进程句柄
HMODULE * lphModule,//模块的数组
DWORD cb, //数组的长度
LPDWORD lpcbNeeded //获取到数据的字节数
);

五 Windows作业(Job)

1 Windows作业
    实际是一个进程组. 能够对作业设置权限,一旦进程增加到作业之内,进程的权限将被作业限制.
    
  2 作业的使用
    须要NT5.0以上支持,全部在Windows.h前定义 
      #define _WIN32_WINNT 0x0500
    2.1 创建一个作业

     HANDLE CreateJobObject(
LPSECURITY_ATTRIBUTES lpJobAttributes,// 安全属性
LPCTSTR lpName ); //名称

返回创建的Job句柄
    2.2 设置作业权限

     BOOL SetInformationJobObject(
HANDLE hJob,//Job句柄
JOBOBJECTINFOCLASS JobObjectInformationClass,//Job权限的类型
LPVOID lpJobObjectInformation,//类型所相应的数据结构的地址
DWORD cbJobObjectInformationLength //类型所相应的数据结构的长度
);

2.3 将进程增加作业

       BOOL AssignProcessToJobObject(
HANDLE hJob, //作业句柄
HANDLE hProcess );//进程句柄

2.4 关闭作业
       CloseHandle
    2.5 结束作业
       使用TerminateJobObject结束作业.可是并非全部情况下,作业内的进程都能被结束.

六 Windows线程

1 Windows线程
    Windows进程中能够运行代码的实体,Windows系统能够调度的运行代码.一个进程中至少有一个或多个线程. 每一个线程是进程的一个任务分支.
    
  2 线程的特点
    2.1 每一个线程有一个ID.
    2.2 每一个线程有自己的安全属性
    2.3 每一个线程有自己的内存栈.
    
  3 进程和线程多任务
    多进程实现的多任务: 因为进程地址空间是属于各自私有, 内存和资源不能共享.
    多线程实现的多任务: 因为线程都是位于同一个进程的地址空间,内存和资源能够共享.
      
  4 线程的运行
    线程的运行方式採用轮询方式运行.
       A -> B -> A -> B.....
       
七 线程的使用

1 定义线程处理函数

    DWORD WINAPI ThreadProc(
LPVOID lpParameter ); //线程參数

2 创建线程

    HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, //安全属性
DWORD dwStackSize, //初始化栈的大小,缺省为0
LPTHREAD_START_ROUTINE lpStartAddress, //线程的函数指针
LPVOID lpParameter, //线程參数
DWORD dwCreationFlags, //创建方式
LPDWORD lpThreadId //返回线程ID
);

返回值是创建好的线程的句柄.
  3 结束线程
    ExitThread
    TerminateThread
  4 线程挂起和运行
    挂起线程
      DWORD SuspendThread( HANDLE hThread  ); 
    运行线程
     DWORD ResumeThread( HANDLE hThread  );
  5 等候线程的结束
    能够使用 WaitForSingleObject 等候线程的
    结束。
  6 关闭线程句柄
    CloseHandle  句柄关掉不代表结束线程,仅仅是释放线程句柄资源

八 线程局部存储 Thread Local Storage

1 因为多个线程使用同一个变量,各个线程都对变量进行操作,那么变量的值会被不同线程操作覆盖。
         
      通常   变量A   <-- 线程A
                     <-- 线程B
                 
      TLS    变量A   <-- 线程A
             变量A   <-- 线程B
             
   2 TLS的使用
     2.1 使用keyword __declspec(thread) 
        __declspec(thread) CHAR * g_pszText2 = NULL;
     2.2 TLS相关API
         TlsAlloc
         TlsSetValue 
         TlsGetValue
         TlsFree

// winJob.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <Windows.h>
#include <conio.h> CHAR * g_pszText1 = NULL; //全部子线程共享一个全局变量
//使用keyword定义TLS变量
__declspec(thread) CHAR * g_pszText2 = NULL; void Print( CHAR * pszText )
{
printf("\n");
printf("+++++++++++++++ %s +++++++++++++++++++++++++\n",pszText);
printf( " Text1: %s\n", g_pszText1 );
printf( "Text2: %s\n", g_pszText2 );
printf("++++++++++++++++++++++++++++++++++++++++++++++\n");
printf("\n");
} DWORD WINAPI PrintProc( LPVOID pParam )
{
CHAR * pszText = (CHAR *)pParam; g_pszText1 = (CHAR *)malloc( 100 );
memset( g_pszText1, 0, 100 );
strcpy( g_pszText1, pszText ); g_pszText2 = (CHAR *)malloc( 100 );
memset( g_pszText2, 0, 100 );
strcpy( g_pszText2, pszText ); while( 1 ){
Print( pszText);
Sleep( 1000 );
}
return 0;
} void CreateTls( )
{
DWORD dwThread = 0;
CHAR szText1[] = "Thread 1----------";
HANDLE hThread = CreateThread( NULL, 0, PrintProc, szText1, 0, &dwThread ); CHAR szText2[] = "-----Thread 2-----";
hThread = CreateThread( NULL, 0, PrintProc, szText2, 0, &dwThread ); CHAR szText3[] = "----------Thread 3";
hThread = CreateThread( NULL, 0, PrintProc, szText3, 0, &dwThread ); getch( );
} HANDLE Create( LPSTR pszPath )
{
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
si.cb = sizeof( si );
CreateProcess( pszPath,NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi );
return pi.hProcess;
} void Job( )
{ //创建Job对象
HANDLE hJob = CreateJobObject( NULL, "MyJob" );
//设置权限
JOBOBJECT_BASIC_UI_RESTRICTIONS ui = {0};
//限制操作剪贴板
ui.UIRestrictionsClass = JOB_OBJECT_UILIMIT_READCLIPBOARD|JOB_OBJECT_UILIMIT_WRITECLIPBOARD; //ui的类型与这个參数有关
SetInformationJobObject( hJob,JobObjectBasicUIRestrictions, &ui, sizeof(ui) ); //创建进程
HANDLE hProc = Create( "C:\\Windows\\System32\\msinfo32.exe" );
//将进程增加作业
AssignProcessToJobObject( hJob, hProc ); /*从控制台读取一个字符,但不显示在屏幕上*/
getch( );
//结束作业
TerminateJobObject( hJob, 0 );
//关闭Job
CloseHandle( hJob );
} DWORD WINAPI ThreadProc1( LPVOID pParam )
{
DWORD nValue = (DWORD)pParam;
for( int nIndex=0; nIndex<10; nIndex++ ){
printf( "Thread Proc1-------%d\n", nValue*nIndex );
Sleep( 1000 );
}
return 0;
} DWORD WINAPI ThreadProc2( LPVOID pParam )
{
while( 1 ){
printf( "-------Thread Proc2\n" );
Sleep( 1000 );
}
return 0;
} void CreateThread( )
{
DWORD nValue = 100;
//创建一个挂起的线程
DWORD nThreadID = 0;
HANDLE hThread = CreateThread( NULL, 0,ThreadProc1, (LPVOID)nValue, CREATE_SUSPENDED, &nThreadID );
printf( "Thread 1 ID: %d\n", nThreadID );
printf( "Thread 1 Handle: %p\n", hThread );
//运行线程
ResumeThread( hThread ); //等候线程1结束
WaitForSingleObject( hThread, INFINITE );
CloseHandle( hThread ); //创建一个立马运行的线程
hThread = CreateThread( NULL, 0, ThreadProc2, NULL, 0, &nThreadID ); printf( "Thread 2 ID: %d\n", nThreadID );
printf( "Thread 2 Handle: %p\n", hThread );
//挂起线程
//SuspendThread( hThread ); Sleep(5000);
#if 0
//会退出程序,可是线程不会退
ExitThread(2); Sleep(2000);
printf( "Thread ExitThread " );
#endif
//结束线程
TerminateThread(hThread,1); //句柄关掉不代表结束线程,仅仅是释放线程句柄资源
CloseHandle( hThread );
} int _tmain(int argc, _TCHAR* argv[])
{
//Job( ); //CreateThread(); CreateTls(); //获得字符输入,堵塞
getch();
return 0;
}

走进windows编程的世界-----windows进程的更多相关文章

  1. [C#] 走进异步编程的世界 - 在 GUI 中执行异步操作

    走进异步编程的世界 - 在 GUI 中执行异步操作 [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5877042.html 序 这是继<开始接 ...

  2. 走进异步编程的世界 - 在 GUI 中执行异步操作

    转载:https://www.cnblogs.com/liqingwen/p/5877042.html 走进异步编程的世界 - 在 GUI 中执行异步操作 [博主]反骨仔 [原文地址]http://w ...

  3. [C#] 走进异步编程的世界 - 开始接触 async/await

    走进异步编程的世界 - 开始接触 async/await 序 这是学习异步编程的入门篇. 涉及 C# 5.0 引入的 async/await,但在控制台输出示例时经常会采用 C# 6.0 的 $&qu ...

  4. 走进异步编程的世界 - 开始接触 async/await

    [C#] 走进异步编程的世界 - 开始接触 async/await   走进异步编程的世界 - 开始接触 async/await 序 这是学习异步编程的入门篇. 涉及 C# 5.0 引入的 async ...

  5. [C#] 走进异步编程的世界 - 开始接触 async/await(转)

    原文链接:http://www.cnblogs.com/liqingwen/p/5831951.html 走进异步编程的世界 - 开始接触 async/await 序 这是学习异步编程的入门篇. 涉及 ...

  6. 走进异步编程的世界 - 开始接触 async/await(转)

    序 这是学习异步编程的入门篇. 涉及 C# 5.0 引入的 async/await,但在控制台输出示例时经常会采用 C# 6.0 的 $"" 来拼接字符串,相当于string.Fo ...

  7. [C#] 走进异步编程的世界 - 剖析异步方法(上)

    走进异步编程的世界 - 剖析异步方法(上) 序 这是上篇<走进异步编程的世界 - 开始接触 async/await 异步编程>(入门)的第二章内容,主要是与大家共同深入探讨下异步方法. 本 ...

  8. [C#] 走进异步编程的世界 - 剖析异步方法(下)

    走进异步编程的世界 - 剖析异步方法(下) 序 感谢大家的支持,这是昨天发布<走进异步编程的世界 - 剖析异步方法(上)>的补充篇. 目录 异常处理 在调用方法中同步等待任务 在异步方法中 ...

  9. 走进异步编程的世界--async/await项目使用实战

    起因:今天要做一个定时器任务:五分钟查询一次数据库发现超时未支付的订单数据将其状态改为已经关闭(数据量大约100条的情况) 开始未使用异步: public void SelfCloseGpPayOrd ...

随机推荐

  1. 改变,从跨出第一步開始——记海大ITAEM团队首次IT讲座掠影

    之前以前写了"行动带来力量,周三(5月7日)晚IT讲座通知",昨晚已经跨出了第一步.让我们还是看举办者骆宏的QQ空间的文字吧.尽管未能到现场助兴,但看着海大学子在不断挑战自己,进而 ...

  2. 第三篇——第二部分——第六文 监控SQL Server镜像

    原文:第三篇--第二部分--第六文 监控SQL Server镜像 原文出处:http://blog.csdn.net/dba_huangzj/article/details/26846203 要优化, ...

  3. Android开发之Handler的用法(源码分享)

    Handler主要接受子线程发送的数据, 并用此数据配合主线程更新UI.. 当应用程序启动时.Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件,进行事件分发. ...

  4. [数字dp] hdu 3565 Bi-peak Number

    意甲冠军: 为了范围[X,Y],的最大位数的范围内的需求高峰和值多少. 双峰是为了满足一些规定数量 你可以切两 /\ /\ 形式. 思维: dp[site][cur][ok]  site地点  面的数 ...

  5. RH253读书笔记(10)-Appendix A Installing Software

    Appendix A Installing Software Below are a few methods to locate and install required packages. You ...

  6. 使用Visual Studio 2010写Data Url生成工具C#版本

    声明:本文系本人按照真实经历原创.未经许可,谢绝转载. 此文百度经验版本号:怎样用Visual Studio 2010打造Data Url生成工具 源代码下载:用Visual Studio 2010编 ...

  7. Scrum总结

    Scrum总结一个轻量级的软件开发方法 Scrum是一个敏捷开发框架,是一个增量迭代的开发过程..在这个框架整个开发周期由若干个小的跌代周期,每个小的的跌代周期称为一个Sprint,每个Sprint的 ...

  8. 从涂鸦到发布——理解API的设计过程(转)

    英文原文:From Doodles to Delivery: An API Design Process 要想设计出可以正常运行的Web API,对基于web的应用的基本理解是一个良好的基础.但如果你 ...

  9. MYSQL 优化指南

    数据库设计原则   标准化和规范化 数据库设计范式(3NF)   第一范式 数据属性唯一标示 在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关 ...

  10. thinkphp学习笔记10—看不懂的路由规则

    原文:thinkphp学习笔记10-看不懂的路由规则 路由这部分貌似在实际工作中没有怎么设计过,只是在用默认的设置,在手册里面看到部分,艰涩难懂. 1.路由定义 要使用路由功能需要支持PATH_INF ...