先来明确下概念:

进程和线程:

进程:进程是一个正在运行的程序,它拥有自己的虚拟地址空间,用有自己的代码,数据和其他系统资源,一个进程也包含了。一个或者多个运行在此进程内的线程。

线程:线程是进程内执行代码的独立实体。

总结下:进程和线程的关系是,进程用有线程。记得上操作系统的时候说区别时提到过,进程是系统分配资源的单位,线程是系统调度的单位。线程的引入了为了减少系统在进行进程调度的时候,减少进程上下文切换代价而引入的。操作系统创建进程后,会创建一个线程执行进程中的代码,这个线程称为主线程,由这个主线程创建的线程称为该进程的辅助线程。

程序启动:

上课的时候老师说程序的入口函数是main函数。但现在得改变观念了。

操作系统并不是真正的调用main函数,而是去调用C/C++运行期启动函数,这函数去会初始化C/C++运行期库。C/C++运行期启动函数会调用程序入口函数main。

看下win32程序启动过程:系统调用CreateProcess函数(创建进程内核对象)-------->创建主线程(执行C/C++运行期启动代码)----------->C/C++运行期启动代码(调用main函数)--------------->main函数(程序执行)

缺少main函数会出现如下错误:

image

 

父进程传递给子进程的数据结构:STARTUPINFO:

STARTUPINFO是结构体类型。由父进程传递给子进程。子进程可以通过GetStartupInfo函数来获取父进程传递给它的信息。

函数:void GetStartupInfo(LPSTARTUPINFO lpStartupInfo)//lp表示指针类型。

调用GetStartupInfo函数时我们要先定义一个STARTUPINFO的结构体对象,其中我们需要使用sizeof来获得其自身的大小:

STARTUPINFO si = {sizeof(si)};网上似乎有同学问改成si.cb =sizeof(si);这样是不行的。因为这时候si这个结构体对象还未定义好,所以不能去地址,取变量。

可以改成:STRARTUPINFO = si; si.cb = sizeof(si);但是这样不能对STARTUPINFO的其它参数默认赋值;

可以:STARTUPINFO si = {0}; si.cb = sizeof(si); 但是这样岂不是多此一举。

 

CreateProcess函数:

创建进程的时候调用CreateProcess函数。其函数原型为:

CreateProcess(

LPCSTR lpApplicationName,//可执行文件的名称

LPSTR   lpCommandLine,//指定传递给执行模块的参数

LPSECURITY_ATTRIBUTES   lpProcessAttributes,  //进程安全性,NULL表示默认安全属性

LRSECURITY_ATTRIBUTES   lpThreadAttributes,//线程安全性,NULL表示默认安全属性

BOOL bInheritHandles,  //指定了当前进程可以被继承句柄是否可以被新进程继续

DWORD    dwCreationFlags,   //指定了新进程的优先级和其他创建标识

LPVOID     lpEnvironment,     //指定了新进程使用的环境变量

LPCSTR     lpCurrentDirectory,   //进程使用的当前目录

LPSTARTUPINFO   lpStartupInfo,  //指定了新进程中主窗口的位置,大小和标准句柄等。

LPPROCESS_INFORMATION   lpProcessInformation  // 返回新进程的标识信息

);

这函数的参数挺多。http://baike.baidu.com/view/697167.htm

创建进程的例子:(书上的)

//创建进程
#include <stdio.h>
#include<windows.h>


int main(int argc, char *argv[])
{
    char szCommandLine[]="cmd";
    STARTUPINFO si={0};
    si.cb= sizeof(si);
    PROCESS_INFORMATION pi;
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = TRUE;

    BOOL bRet = ::CreateProcess(
        NULL,
        szCommandLine,
        NULL,
        NULL,
        FALSE,
        CREATE_NEW_CONSOLE,
        NULL,
        NULL,
        &si,
        &pi);
    if (bRet)
    {
        ::CloseHandle(pi.hThread);
        ::CloseHandle(pi.hProcess);
        printf("新的进程ID号:%d\n",pi.dwProcessId);
        printf("新进程的主线程ID号:%d\n",pi.dwThreadId);
    }
    system("pause");
    return 0;

}
 posted on 2011-12-31 21:02  mfslog  阅读(506)  评论(0编辑  收藏  举报