博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
走进windows编程的世界-----windows进程
阅读量:5011 次
发布时间:2019-06-12

本文共 6314 字,大约阅读时间需要 21 分钟。

 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 
#include
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;}

 

转载于:https://www.cnblogs.com/mfrbuaa/p/4357058.html

你可能感兴趣的文章
iOS开发UI之KVC(取值/赋值) - KVO (观察某个对象的某个属性的改变)
查看>>
1.7 将一个MxN矩阵所有为0的元素所在行和列全部置0
查看>>
删除U盘时提示无法停止‘通用卷’设备的解决方法!!不要每次都硬拔了,对电脑有不小的损害!!!...
查看>>
Java中接口与接口和类之间的关系
查看>>
芯片TPS70925
查看>>
linux shell 发送email 附件
查看>>
人群密度估计 CrowdCount
查看>>
JSON.parse()和JSON.stringify()
查看>>
.net 常用正则表达式
查看>>
Java泛型中的标记符含义:
查看>>
初遇GitHub
查看>>
[C# 网络编程系列]专题八:P2P编程
查看>>
Jsの练习-数组常用方法 -forEach()
查看>>
动态绑定treeview的方法
查看>>
jvm参数
查看>>
3-1 案例环境初始化
查看>>
读《构建之法》第四章和十七章有感
查看>>
01背包
查看>>
开发一个12306网站要多少钱?技术分析12306合格还是不合格
查看>>
Selenium 入门到精通系列:六
查看>>