博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MFC之AfxbeginThread 线程 创建、挂起、释放、结束、退出
阅读量:4303 次
发布时间:2019-05-27

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

MFC之AfxbeginThread 线程 创建、挂起、释放、结束、退出

本文简单阐述了如何使用一个afxbeginthread创建一个线程(两种方法,使用默认设置,使用自主设置参数),以及一些如同,挂起,释放。边界锁等操作。

 

①.h文件添加声明

public:CWinThread *m_pthread;CWinThread *m_pthread2; static UINT __cdecl  hellothread(LPVOID lparam); //4.掐指算了一下。说是>vs 2005的编译器定义线程函数都需要添加两个宏,即UINT _cdeclstatic UINT __cdecl testthread(LPVOID lparam);CCriticalSection g_criticalsection; //边界锁,线程间同步用的。 //20190319 updata    如果创建了两个线程最好使用两个线程开关。一个开关,好像无法控制两个线程。BOOL tflag;  //用作线程开关。

 

//1.线程同步有四种方式,边界锁、互斥量(CMutex)、信号灯、CEvent(事件)。不过对于CEvent和边界锁感觉能理解。

//http://blog.csdn.net/i_likechard/article/details/77531457    这个是介绍Cevent在线程中的用法的。
//2.边界锁CCriticalSection 和互斥量Cmutex很像,唯一的差别是,CMutex能够在进程间使用。
//3.网上也有通过UINT hellothread(LPVOID lparam);这种方式直接定义的;不过运行的时候会报错。

 

②.cpp 文件添加初始化及定义 

//特别注意,线程函数定义的代码位置一定要位于使用afxbeginthread()之前

在CthreadDlg::CpratiseDlg(CWnd*pParent):CDialogEx(CpratiseDlg::IDD,pParent)函数中,添加如下代码:将线程开关置为真。我的工程名为thread。

tflag=true;

 

以下为线程函数定义:

UINT __cdecl CthreadDlg::hellothread(LPVOID lparam) //线程1函数定义{    //CthreadDlg *threadol = new CthreadDlg;     //CthreadDlg *threadol=new CthreadDlg();     CthreadDlg *threadol=(CthreadDlg*) lparam;      //以上3句代码均可实现将this指针传递给threadol对象。通过 "threadol->" 的方式,使得线程1中可以调用主线程的所有函数,全局变量,控件。    while (threadol->tflag) //通过线程开关控制线程1是否一直开启。    {          //AfxMessageBox("hellothread");         //threadol->m_static1.SetWindowTextA("第 1 个线程\n");          threadol->g_criticalsection.Lock(); //边界锁锁定        // 同步锁中间可添加需要保护的操作代码,如操作txt文档读、看、写时等。        threadol->g_criticalsection.Unlock();//边界锁解除     }    return 0;} UINT __cdecl CthreadDlg::testthread( LPVOID lparam )//线程2函数定义{    CthreadDlg *threadol = (CthreadDlg*)lparam;     //线程2中写的比较简单。可以仿造线程1hellothread进行编写。    while(threadol->tflag)    {        //do something        threadol->g_criticalsection.Lock(); //边界锁锁定        // 同步锁中间可添加需要保护的操作代码,如操作txt文档读、看、写时等。        threadol->g_criticalsection.Unlock();//边界锁解除    }    return 0; }

③.cpp中OnInitDialog()函数中添加; //采用了两种方式来实现线程初始化,都是使用的afxBeginthread();

 tflag=TRUE; //将想成开关置为真。使得可以进行线程循环。  //m_pthread = AfxBeginThread(hellothread,(LPVOID)this);    //第一个 线程1 m_pthread1 = AfxBeginThread(hellothread,this,THREAD_PRIORITY_NORMAL,0,0);  //参数意义:(线程函数名,传递当前主对话框指针到线程函数中,普通级别,默认栈大小,自启动) //第二个 线程2 m_pthread2=AfxBeginThread(testhread,this,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED); //参数意义:(函数名称,当前主对话框指针,优先级为“一般”的线程,默认栈大小,创建时挂起)

 

④线程的暂停、开始

//以下操作如同暂停、开始可在某两个button控件的点击事件中添加,实现对线程的控制。

SuspendThread(m_pthread2->m_hThread); //挂起第二个线程。“暂停”ResumeThread(m_pthread2->m_hThread); //释放第二个线程。”播放“

//对于suspendthread和resumethread这两个函数,其中的参数为句柄。用afxbeginthread创建的线程返回值为一个指针。不过通过这个指针m_pthread2,可以找到m_hThread。

⑤查看线程

调用任务管理器,选择进程,单击查看,单击选择列,勾选“线程”。即可在任务管理器中查看。

⑥退出关闭一个线程(以下关闭代码可以添加到某button按钮下,如ok)

较好的方式:线程函数的return 0;这样是最安全的。会释放所有资源。

例如:

void CthreadDlg::OnBnClickedOk(){    // TODO: 在此添加控件通知处理程序代码     tflag=FALSE;      //线程开关置为假    WaitForSingleObject(m_pthread,100);     WaitForSingleObject(m_pthread2,100);     g_criticalsection.Lock();    //file.Close();    g_criticalsection.Unlock();    CDialogEx::OnOK();   //关闭对话框}

不正常的方式:exitthread();

例如:

DWORD exitcode2;GetExitCodeThread(m_pthread2,&exitcode2);ExitThread(exitcode2);   

 //运行了这句话之后,程序直接关闭了。由于我线程创建了两个。用这句话只能结束一个线程。所以这个东西不安全。不过对于只有一个线程的,在某种情况下使用也是很快。

//2018-7-19 09:25:18 整理了代码段

原文:https://blog.csdn.net/i_likechard/article/details/51544120 
 

你可能感兴趣的文章
【Oracle】day01_数据类型_DDL语句_DML语句
查看>>
【Orace】day02_字符串_数值_日期_NULL相关函数
查看>>
【Oracle】day03_查询语句_聚合函数_关联查询
查看>>
【Oracle】day04_子查询_分页查询_DECODE_排序_集合操作_高级分组
查看>>
【Oracle】day05_视图_序列_索引_约束
查看>>
【JDBC】day01_Java连接Oracle数据库过程及常用方法
查看>>
【JDBC】day02_PreparedStatement_元数据
查看>>
【JDBC】day03_数据库连接池
查看>>
【JDBC】day04_事务_批处理_自动主键_DAO
查看>>
有关线程调度问题
查看>>
MyEclipse注册码生成代码
查看>>
Java中Socket阻塞的原因
查看>>
【html】day01_Web概述_html工作原理_XML与HTML_乱码问题
查看>>
【html】day02_标记_注释_HTML文档类型
查看>>
【html】day03_head_文本元素_行内元素
查看>>
【html】day04_图像和超链接
查看>>
Java程序员面试中的多线程问题
查看>>
数据库连接池问题
查看>>
java.sql.SQLException的常见原因
查看>>
【html】day05_表格_表单
查看>>