zoukankan      html  css  js  c++  java
  • 走进windows编程的世界-----windows进程

     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("
    ");
    	printf("+++++++++++++++ %s +++++++++++++++++++++++++
    ",pszText);
        printf( " Text1: %s
    ", g_pszText1 );
        printf( "Text2: %s
    ", g_pszText2 );
    	printf("++++++++++++++++++++++++++++++++++++++++++++++
    ");
    	printf("
    ");
    }
    
    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
    ",  nValue*nIndex );
            Sleep( 1000 );
        }
        return 0;
    }
    
    DWORD WINAPI ThreadProc2( LPVOID pParam )
    {
        while( 1 ){
            printf( "-------Thread Proc2
    " );
            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
    ", nThreadID );
        printf( "Thread 1 Handle: %p
    ", hThread );
        //运行线程
        ResumeThread( hThread );
    
        //等候线程1结束
        WaitForSingleObject( hThread, INFINITE );
        CloseHandle( hThread );
    
        //创建一个立马运行的线程
        hThread = CreateThread( NULL, 0, ThreadProc2, NULL, 0, &nThreadID );
        
    	printf( "Thread 2 ID: %d
    ", nThreadID );
        printf( "Thread 2 Handle: %p
    ", 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;
    }
    
    



  • 相关阅读:
    Java基础_0205: 程序逻辑结构
    java基础_0204:运算符
    Centos 7 安装MySQL
    Maven 入门
    winx64 MySQL 5.7绿色版安装步骤
    hadoop环境搭建
    配置虚拟机 Linux 静态IP
    JDK开发环境搭建及环境变量配置
    设计模式之命令模式详解(故事版)
    设计模式之 外观模式详解(Service第三者插足,让action与dao分手)
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4357058.html
Copyright © 2011-2022 走看看