queueuserworkitemqueueuserworkitem 线程池异步任务为什么没有被立即执行
queueuserworkitem 时间:2021-01-17 阅读:(
)
C# ThreadPool和Thread多线程 问
/ / 线程池示例
using System;
using System.Threading;
public class Test
{
// 存放要计算的数值的字段
static double number1 = -1;
static double number2 = -1;
public static void Main()
{
// 获取线程池的最大线程数和维护的最小空闲线程数
int maxThreadNum, portThreadNum;
int minThreadNum;
ThreadPool.GetMaxThreads(out maxThreadNum, out portThreadNum);
ThreadPool.GetMinThreads(out minThreadNum, out portThreadNum);
Console.WriteLine("最大线程数:", maxThreadNum);
Console.WriteLine("最小空闲线程数:", minThreadNum);
// 函数变量值
int x = 15600;
// 启动第一个任务:计算x的8次方
Console.WriteLine("启动第一个任务:计算的8次方。
", x);
ThreadPool.QueueUserWorkItem(new WaitCallback(TaskProc1), x);
// 启动第二个任务:计算x的8次方根
Console.WriteLine("启动第二个任务:计算的8次方根。
", x);
ThreadPool.QueueUserWorkItem(new WaitCallback(TaskProc2), x);
// 等待,直到两个数值都完成计算
while (number1 == -1 || number2 == -1) ;
// 打印计算结果
Console.WriteLine("y() = ", x, number1 + number2);
}
// 启动第一个任务:计算x的8次方
static void TaskProc1(object o)
{
number1 = Math.Pow(Convert.ToDouble(o), 8);
}
// 启动第二个任务:计算x的8次方根
static void TaskProc2(object o)
{
number2 = Math.Pow(Convert.ToDouble(o), 1.0 / 8.0);
}
}回调函数 与 线程 有何区别
普通函数与回调函数的区别:
对普通函数的调用:调用程序发出对普通函数的调用后,程序执行立即转向被调用函数执行,直到被调用函数执行完毕后,再返回调用程序继续执行。
从发出调用的程序的角度看,这个过程为“调用-->等待被调用函数执行完毕-->继续执行”
对回调函数调用:调用程序发出对回调函数的调用后,不等函数执行完毕,立即返回并继续执行。
这样,调用程序执和被调用函数同时在执行。
当被调函数执行完毕后,被调函数会反过来调用某个事先指定函数,以通知调用程序:函数调用结束。
这个过程称为回调(Callback),这正是回调函数名称的由来。
如何创建Worker线程
创建Worker线程首先定义一个线程函数,然后调用AfxBeginThread函数。
AfxBeginThread函数的定义如下:
CWinThread* AfxBeginThread(
AFX_THREADPROC pfnThreadProc,
LPVOID pParam,
int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize= 0,
DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);
其中:
pfnThreadProc:线程函数。
pParam:传递给线程函数的参数。
nPriority:线程的优先级。
默认值为THREAD_PRIORITY_NORMAL。
nStackSize:线程的堆栈大小。
默认值为0。
dwCreateFlags:线程的创建标志。
默认值为0,表示线程产生后立即执行。
如果其值为CREATE_SUSPENDED表示线程产生后暂停执行,直到CWinThread::ResumeThread函数被调用。
lpSecurityAttrs:表示线程的安全属性。
默认值为NULL。
函数返回值是一个指向新创建线程对象的指针。
在MFC的THRDCORE.CPP中,AfxBeginThread函数的相关代码如下:
// THRDCORE.CPP
CWinThread* AFXAPI AfxBeginThread(
AFX_THREADPROC pfnThreadProc,
LPVOID pParam,
int nPriority,
UINT nStackSize,
DWORD dwCreateFlags,
LPSECURITY_ATTRIBUTES lpSecurityAttrs)
{
ASSERT(pfnThreadProc != NULL);
CWinThread* pThread = DEBUG_NEW CWinThread(
pfnThreadProc,
pParam);
ASSERT_VALID(pThread);
if (!pThread->CreateThread(
dwCreateFlags|CREATE_SUSPENDED,
nStackSize,
lpSecurityAttrs))
{
pThread->Delete();
return NULL;
}
VERIFY(pThread->SetThreadPriority(nPriority));
if (!(dwCreateFlags & CREATE_SUSPENDED))
VERIFY(pThread->ResumeThread() != (DWORD)-1);
return pThread;
}
从MFC代码中可以看出,AfxBeginThread函数首先创建CWinThread对象,然后调用CWinThread::CreateThread函数。
CWinThread::CreateThread函数调用_beginthreadex函数创建线程。
此外,AfxBeginThread和CWinThread::CreateThread还做了一些应用程序框架所需的内部数据的初始化工作。
在MFC的AFXWIN.H中定义了线程函数类型AFX_THREADPROC:
typedef UINT (AFX_CDECL *AFX_THREADPROC)(LPVOID);
从定义中可以看出,线程函数返回一个UINT值。
此外,线程函数传递一个LPVOID参数,一般在使用中指向用户自定义的数据结构。
线程函数是由系统调用的,是一个callback函数,所以必须是个全局函数或者是C++类static成员函数,而不能是C++类成员函数。
(1)创建1个基于对话框的应用程序,名称为Demo。
(2)在IDD_DEMO_DIALOG对话框资源中添加控件,如表所示。
类型
ID
标题
Static
IDC_STATIC
数据:
Edit
IDC_DATA
Button
IDC_BEGIN_THREAD
启动线程
(3)在文件中定义线程传递参数的数据结构,代码如下:
// DemoDlg.h
typedef struct THREAD_PARAM
{
HWND hWnd;
int nData;
}_THREAD_PARAM;
(4)在CDemoDlg类中添加成员变量,代码如下:
// DemoDlg.h
protected:
THREAD_PARAM m_ThreadParam;
(5)在CDemoDlg类的构造函数和析构函数中添加如下代码:
// DemoDlg.cpp
CDemoDlg::CDemoDlg(CWnd* pParent /*=NULL*/)
: CDialog(CDemoDlg::IDD, pParent)
{
// ...
m_ThreadParam.nData = 0;
}
(6)在CDemoDlg类的OnInitDialog函数中添加如下代码:
// DemoDlg.cpp
BOOL CDemoDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// …
SetDlgItemInt(IDC_DATA, m_ThreadParam.nData);
return TRUE;
}
(7)在文件中定义线程消息,代码如下:
// DemoDlg.h
#define WM_THREADMSG WM_USER+1
(8)在文件中定义线程函数,代码如下:
// DemoDlg.h
UINT ThreadProc(LPVOID pParam);
// DemoDlg.cpp
UINT ThreadProc(LPVOID pParam)
{
//线程参数
THREAD_PARAM* pThreadParam = (THREAD_PARAM*)pParam;
for (int n = 0; n < 10; n++)
{
Sleep(100);
pThreadParam->nData++;
//向主线程窗口发送消息
::PostMessage(pThreadParam->hWnd, WM_THREADMSG, 0, 0);
}
return 0;
}
(9)在CDemoDlg类中为Button控件添加BN_CLICKED添加消息处理函数,代码如下:
// DemoDlg.cpp
void CDemoDlg::OnBeginThread()
{
m_ThreadParam.hWnd = m_hWnd;
//启动线程
AfxBeginThread(ThreadProc, &m_ThreadParam);
}
(10)在CDemoDlg类中添加自定义消息处理函数,代码如下:
// DemoDlg.h
afx_msg LRESULT OnMsgFunc();
// DemoDlg.cpp
BEGIN_MESSAGE_MAP(CDemoDlg, CDialog)
ON_MESSAGE(WM_THREADMSG, OnMsgFunc)
END_MESSAGE_MAP()
LRESULT CDemoDlg::OnMsgFunc()
{
SetDlgItemInt(IDC_DATA, m_ThreadParam.nData);
return 1;
}queueuserworkitem 线程池异步任务为什么没有被立即执行
那你其他的线程不要独占CPU,在必要的地方添加语句sleep(10)休眠下,就可以释放CPU给其他线程了,你所创建的线程就可以及时执行了。
imidc怎么样?imidc彩虹数据或彩虹网络现在促销旗下日本多IP站群独立服务器,原价159美元的机器现在只需要88美元,而且给13个独立IPv4,30Mbps直连带宽,不限制月流量!IMIDC又名为彩虹数据,rainbow cloud,香港本土运营商,全线产品都是商家自营的,自有IP网络资源等,提供的产品包括VPS主机、独立服务器、站群独立服务器等,数据中心区域包括香港、日本、台湾、美国和南非...
国外商家提供Windows系统的并不常见,CheapWindowsVPS 此次提供的 2 款 VPS 促销套餐,提供 5 折永久优惠码,优惠后月付 4.5 美元起,价格还是挺诱人的,VPS 不限流量,接入 1Gbps 带宽,8 个机房皆可选,其中洛杉矶机房还提供亚洲优化网络供选择,操作系统有 Windows 10 专业版、2012 R2、2016、Linux等。Cheap Windows VPS是...
弘速云怎么样?弘速云是创建于2021年的品牌,运营该品牌的公司HOSU LIMITED(中文名称弘速科技有限公司)公司成立于2021年国内公司注册于2019年。HOSU LIMITED主要从事出售香港vps、美国VPS、香港独立服务器、香港站群服务器等,目前在售VPS线路有CN2+BGP、CN2 GIA,该公司旗下产品均采用KVM虚拟化架构。可联系商家代安装iso系统。点击进入:弘速云官方网站地址...
queueuserworkitem为你推荐
缓冲区溢出教程适合黑客初级学者使用的黑客工具有那些 、依赖注入Spring 的依赖注入是什么意思?ps抠图技巧请教PS抠图技巧!!!ps抠图技巧photoshop抠图技巧安卓应用平台哪个手机应用平台的软件比较正版,安全?如何建立一个网站要建立一个网站怎么弄啊?iphone越狱后怎么恢复iPhone越狱后怎么恢复?安装迅雷看看播放器怎样安装迅雷看看播放器网管工具网吧工具有什么?服务器连接异常服务器连接异常是怎么回事啊,怎么解决
购买域名 播放vps上的视频 vps.net gomezpeer wordpress技巧 lamp配置 eq2 福建天翼加速 大容量存储器 网站木马检测工具 idc是什么 免费防火墙 服务器是干什么的 php空间购买 美国网站服务器 服务器硬件防火墙 独享主机 网站加速软件 监控服务器 网页加速 更多