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给其他线程了,你所创建的线程就可以及时执行了。
外贸主机哪家好?抗投诉VPS哪家好?无视DMCA。ParkinHost今年还没有搞过促销,这次parkinhost俄罗斯机房上新服务器,母机采用2个E5-2680v3处理器、128G内存、RAID10硬盘、2Gbps上行线路。具体到VPS全部200Mbps带宽,除了最便宜的套餐限制流量之外,其他的全部是无限流量VPS。ParkinHost,成立于 2013 年,印度主机商,隶属于 DiggDigi...
10GBIZ服务商经常有看到隔壁的一些博客分享内容,我翻看网站看之前有记录过一篇,只不过由于服务商是2020年新成立的所以分享内容比较谨慎。这不至今已经有将近两年的服务商而且云服务产品也比较丰富,目前有看到10GBIZ服务商有提供香港、美国洛杉矶等多机房的云服务器、独立服务器和站群服务器。其中比较吸引到我们用户的是亚洲节点的包括香港、日本等七星级网络服务。具体我们看看相关的配置和线路产品。第一、香...
Sharktech荷兰10G带宽的独立服务器月付319美元起,10Gbps共享带宽,不限制流量,自带5个IPv4,免费60Gbps的 DDoS防御,可加到100G防御。CPU内存HDD价格购买地址E3-1270v216G2T$319/月链接E3-1270v516G2T$329/月链接2*E5-2670v232G2T$389/月链接2*E5-2678v364G2T$409/月链接这里我们需要注意,默...
queueuserworkitem为你推荐
站长故事爱迪生发明东西的故事怎么样免费装扮qq空间要怎么免费装扮QQ空间!怎么在qq空间里添加背景音乐如何在qq空间中添加背景音乐二叉树遍历写出二叉树的先序遍历、中序遍历、后序遍历。iphone越狱后怎么恢复iPhone越狱后怎么恢复?网易公开课怎么下载网易公开课的视频该如何下载?腾讯文章怎么在手机腾讯网发文章直播加速手机上什么软件可以帮助直播加速,大神们推荐推荐godaddyGodaddy域名怎么接受网络广告投放网络广告投放有哪些技巧?
cybermonday linode日本 国外服务器网站 腾讯云数据库 seednet google台湾 上海电信测速网站 linode支付宝 中国联通宽带测试 googlevoice hdchina 机柜尺寸 cpu使用率过高怎么办 防盗链 香港打折信息 ddos攻击工具 次世代主机 免费网络电视软件 关闭空间申请 ibm服务器机柜 更多