MFC进程的创建销毁、线程的创建与交互

进程的创建

    STARTUPINFO si;   //**成员DWORD   dwFlags;表示结构体当中哪些成员有效。**STARTF_USESHOWWINDOW|STARTF_USEPOSITION
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));
                         //LPTSTR  pszCmdLine = TEXT("C:\\Windows\\System32\\notedap.exe");改成
                         //TCHAR  pszCmdLine[] = TEXT("C:\\Windows\\System32\\notedap.exe");
                         //Windows核心编程专门有讲这个问题  CreateProcess会修改传递给它的命令行字符串, LPTSTR是字符串指针不能修改....* /
    //char* szCommandLine ="C:\\Program Files (x86)\\KuGou\\KGMusic\\KuGou.exe";
    TCHAR  szCommandLine[] = TEXT("notepad ReadMe.txt");//父进程当前目录下的ReadMe.txt
    ::CreateProcess(NULL,//可执行文件名(必须添加.exe。若未添加路径则只会去当前目录找。so一般为NULL)
                   (LPWSTR)szCommandLine,//传递给执行模块的参数,相当于在运行栏输入szCommandLine(可以在一些目录下自动搜寻exe)
                    NULL,//进程安全性
                    NULL, //线程安全性
                    FALSE,//当前进程的可继承句柄是否可以被新进程继承
                    NULL,//创建标志 如 CREAT_NEW_CONSOLE
                    NULL, //环境变量
                    NULL,//当前目录
                    &si,//父给子进程的显示信息
                    &pi);//此进程的标志信息  ID\句柄
    &pi.dwProcessId;//进程ID
    &pi.dwThreadId;//进程中主线程ID
    &pi.hProcess;//进程内核句柄
    &pi.hThread;//进程中主线程内核句柄

终止进程

    //::ExitProcess(0);  //终止当前进程,退出代码0
    //BOOL bBet=::TerminateProcess(pi.hProcess,-1);//退出代码-1(关闭进程失败)

    HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, //想得到的访问权限
                                    FALSE,        //返回的句柄是否可以被继承
                                    pi.dwProcessId);//进程ID
    BOOL bBet = ::TerminateProcess(hProcess, -1);//(关闭进程成功)

    CloseHandle(hProcess);
    CloseHandle(pi.hProcess);  //不使用就关闭

创建线程

    DWORD dwThreadId;
    HANDLE hHandle;
    hHandle = ::CreateThread(NULL,      //线程安全属性
                             NULL,      //线程堆栈大小
                             ThreadFun, //线程函数起始地址
                             NULL,      //传给线程函数的参数
                             0,         //是否立即启动线程
                             &dwThreadId);//取得线程ID
    //一般使用下面方法
    UINT uId;
    HANDLE hHandleCopy;
    hHandleCopy = (HANDLE)::_beginthreadex(NULL,      //线程安全属性
                               NULL,      //线程堆栈大小
                               ThreadProc, //线程函数起始地址
                               NULL,      //传给线程函数的参数
                               0,         //是否立即启动线程
                               &uId);//取得线程ID

线程函数如下:

//============================================================================================
//线程函数的定义
//DWORD WINAPI ThreadFun()     //参数LPVOID IpParam是必须的
DWORD WINAPI ThreadFun(LPVOID IpParam)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));
    TCHAR  szCommandLine[] = TEXT("C:\\Program Files (x86)\\KuGou\\KGMusic\\KuGou.exe");
    ::CreateProcess(NULL,(LPWSTR)szCommandLine,NULL,NULL,FALSE,NULL,NULL, NULL,&si,&pi);
    return 0;
}
//=============================================================================================
UINT _stdcall ThreadProc(LPVOID IpParam)
{
    ::WaitForSingleObject(g_hEvent,INFINITE);
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));
    TCHAR  szCommandLine[] = TEXT("notepad ReadMe.txt");
    ::CreateProcess(NULL, (LPWSTR)szCommandLine, NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi);
    return 0;
}
//================================================================================================

线程通信交互

    //线程之间的交互(事件内核对象)
    //HANDLE g_hEvent;
    g_hEvent = ::CreateEvent(NULL, //事件对象安全属性
                             FALSE, //是否是手动重置事件对象为未受信(否则系统自动重置)
                             FALSE, //初始状态(受信/未受信)执行中:未受信
                             NULL); //事件对象名称(可用于OpenEvent()函数的第三个参数,类似进程)

    ::WaitForSingleObject(hHandle,     //对象句柄
                          INFINITE);   //等待时间(\毫秒)
    Sleep(10000);
    SetEvent(g_hEvent);
    //RetEvent(g_hEvent); //自动模式下无需重置(自动重置)
    ::WaitForSingleObject(hHandleCopy,INFINITE);  //等待

    //::WaitForMultipleObjects(2,        //对象句柄数量
    //                           h,        //对象句柄数组
    //                           TRUE,     //是否等待所有内核对象变为受信状态(否则有一个就可以)
    //                           INFINITE) //等待时间(\毫秒)
    //很实用,等待指定线程执行完毕(不加这句线程还未执行完毕主线程就已经结束了)

其中SetEvent(g_hEvent);中的g_hEvent是全局变量HANDLE g_hEvent;

SetEvent(g_hEvent)使得事件对象g_hEvent变为受信状态,

此时ThreadProc函数中的::WaitForSingleObject(g_hEvent,INFINITE);函数检测到其为受信时开始执行接下来的代码。

终止线程与终止进程类似,一般不使用终止进程和线程函数,一般使用通信机制告诉要关闭的进程或线程让其自行退出。

强行终止会使得来不及执行析构函数,回收内存,造成内存泄漏。

原文地址:https://www.cnblogs.com/cteng-common/p/progressandthread.html

时间: 2024-10-09 02:12:55

MFC进程的创建销毁、线程的创建与交互的相关文章

Dalvik虚拟机进程和线程的创建过程分析

文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8923484 我们知道,在Android系统中,Dalvik虚拟机是运行Linux内核之上的.如果我们把Dalvik虚拟机看作是一台机器,那么它也有进程 和线程的概念.事实上,我们的确是可以在Java代码中创建进程和线程,也就是Dalvik虚拟机进程和线程.那么,这些Dalvik虚拟机所创建的进程 和线程与其宿主Linux内核的进程和线程有什么关

【进程管理】进程(线程)创建

本节主要研究进程(线程)创建的过程,下文将不区分进程和线程: 基本知识 在linux系统中,第一个进程是系统固有的,是由内核的设计者安排好的:一个新的进程一定要由一个已存在的进程复制出来,而不是创造出来的,其实linux系统并不提供直接创建进 程的方法:创建了子进程以后,父进程可以继续走自己的路,与子进程分道扬镳,但是如果子进程先行exit(),那么将要向父进程发一个信号:父进程也可以选择睡眠,等子进程 exit()以后再去世,然后父进程再继续执行,可使用wait3()某个特定的子进程,wait

Android线程的创建与销毁

摘要: 在Android开发中经常会使用到线程,一想到线程,很多同学就立即使用new Thread(){...}.start()这样的方式.这样如果在一个Activity中多次调用上面的代码,那么将创建多个匿名线程,程序运行的越久可能会越来越慢.因此,需要一个Handler来启动一个线程,以及删除一个线程,保证线程不会重复的创建. 正文: 1.创建Handler的一般方式 一般会使用Handler handler = new Handler(){...}创建.这样创建的handler是在主线程即

转:Android线程的创建与销毁

http://mt.sohu.com/20140813/n403395303.shtml?recsyssohu=2 在Android开发中经常会使用到线程,一想到线程,很多同学就立即使用new Thread(){...}.start()这样的方式.这样如果在一个Activity中多次调用上面的代码,那么将创建多个匿名线程,程序运行的越久可能会越来越慢.因此,需要一个Handler来启动一个线程,以及删除一个线程,保证线程不会重复的创建. 1.创建Handler的一般方式  一般会使用Handle

创建指定大小,当空闲超时还会自动销毁线程的线程池

WO想要Executor线程池,WO还想要限制线程池大小,WO还想要线程闲置超时能自动销毁. 好的- ThreadPoolExecutor mThreadPool = new ThreadPoolExecutor(poolSize, 0, maxIdleTime, TimeUnit.SECONDS, LinkedBlockingQueue<Runnable>()); // poolSize为线程池大小:maxIdleTime为允许的闲置时间,超时即毁 mThreadPool.allowCore

线程的创建与销毁

启动线程:Start,运行  线程的"绑定"/"执行"方法. 销毁线程:Abort,线程消失. 名词:线程的"执行方法" == 线程的"绑定方法" 线程的"绑定方法"/"执行方法",不但可以是当前实例中的方法(如:1),也可以是其它实例中的方法(如:2,需要创建指定类型的实例,然后引用其方法作为"子线程"的"绑定方法"/"执行方法&quo

Android虚拟机学习总结Dalvik虚拟机进程和线程的创建过程分析

Dalvik虚拟机在调用一个成员函数的时候,如果发现该成员函数是一个JNI方法,那么就会直接跳到它的地址去执行.也就是说,JNI方法是直接在本地操作系统上执行的,而不是由Dalvik虚拟机解释器执行.由此也可看出,JNI方法是Android应用程序与本地操作系统直接进行通信的一个手段. Dalvik虚拟机除了可以执行Java代码之外,还可以执行Native代码,也就是C/C++函数.这些C/C++函数在执行的过程中,又可以通过本地操作系统提供的系统调用来创建本地操作系统进程或者线程,也就是Lin

Linux下的进程类别(内核线程、轻量级进程和用户进程)以及其创建方式--Linux进程的管理与调度(四)

本文声明 日期 内核版本 架构 作者 GitHub CSDN 2016-05-12 Linux-4.5 X86 & arm gatieme LinuxDeviceDrivers Linux进程管理与调度-之-进程的创建 本文中出现的,内核线程,轻量级进程,用户进程,用户线程等概念,如果不太熟悉, 可以参见 内核线程.轻量级进程.用户线程三种线程概念解惑(线程≠轻量级进程) Linux进程类别 虽然我们在区分Linux进程类别, 但是我还是想说Linux下只有一种类型的进程,那就是task_str

linux内核线程的创建与销毁

linux将创建内核线程的工作交给了一个专门的内核线程kthreadd来完成,该线程会检查全局链表kthread_create_list,如果为NULL,就会调schedule()放弃cpu进入睡眠状态,否则就取下该链表中的一项创建对应的线程.本文就从khtreadd内核线程的创建开始来展示一下内核线程的创建过程.1 kthreaddlinux2.6.30,创建内核线程是通过kethradd内核守护线程来完成的,虽然机制上有所变化,但是最终还是调用do_fork来完成线程的创建.Kthreadd

Java总结(九)——(线程模块 一(线程的创建(方法一)与启动,线程状态与生命周期,进程与线程))

一.进程与线程 进程:每一个独立运行的程序称为一个进程 线程:线程时一个进程内部的一条执行路径,Java虚拟机允许程序并发的运行多个执行路径 *进程中执行运算的最小单位-->线程<--处理机分配 进程与线程的区别: (1)进程有独立的运行地址空间,一个进程崩溃后不会影响到其他的进程,而线程只是 一个进程中的一个执行路径,如果有一条线程奔溃了,可能会影响到进程中的的其他线程 (2)线程有自己的栈和局部变量,多个线程共享同一进程的地址空间 (3)一个进程至少有一个线程 多线程 (1)多线程 就是在