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给其他线程了,你所创建的线程就可以及时执行了。
欧路云新上了美国洛杉矶cera机房的云服务器,具备弹性云特征(可自定义需要的资源配置:E5-2660 V3、内存、硬盘、流量、带宽),直连网络(联通CUVIP线路),KVM虚拟,自带一个IP,支持购买多个IP,10G的DDoS防御。付款方式:PayPal、支付宝、微信、数字货币(BTC USDT LTC ETH)测试IP:23.224.49.126云服务器 全场8折 优惠码:zhujiceping...
弘速云元旦活动本公司所销售的弹性云服务器、虚拟专用服务器(VPS)、虚拟主机等涉及网站接入服务的云产品由具备相关资质的第三方合作服务商提供官方网站:https://www.hosuyun.com公司名:弘速科技有限公司香港沙田直营机房采用CTGNET高速回国线路弹性款8折起优惠码:hosu1-1 测试ip:69.165.77.50地区CPU内存硬盘带宽价格购买地址香港沙田2-8核1-16G20-...
80vps怎么样?80vps最近新上了香港服务器、美国cn2服务器,以及香港/日本/韩国/美国多ip站群服务器。80vps之前推荐的都是VPS主机内容,其实80VPS也有独立服务器业务,分布在中国香港、欧美、韩国、日本、美国等地区,可选CN2或直连优化线路。如80VPS香港独立服务器最低月付420元,美国CN2 GIA独服月付650元起,中国香港、日本、韩国、美国洛杉矶多IP站群服务器750元/月...
queueuserworkitem为你推荐
木马病毒什么是木马病毒?博客外链请问怎么利用博客做外链呢快速美白好方法有什么好方法能快速美白?天天酷跑刷金币天天酷跑如何刷分刷金币?神雕侠侣礼包大全神雕侠侣手游每天送的元宝买什么合适人人逛街包公免费逛街打一成语免费qq空间装扮有办法免费装扮QQ空间吗??ejb开发什么是EJB?它是干什么的?和JAVA,JSP有关系吗?他们各有什么特点和用途?发邮件怎么发发邮件怎么发?三星s8什么时候上市三星s8什么时候上市 三星s8上市时间
hostigation directadmin 轻量 网通服务器ip 国外网站代理服务器 亚洲小于500m 789电视 双线主机 双十一秒杀 国外代理服务器软件 如何安装服务器系统 drupal安装 石家庄服务器托管 服务器防火墙 小夜博客 亿库 带宽测速 ftp服务器架设 魔兽世界服务器维护 个人web服务器软件 更多