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给其他线程了,你所创建的线程就可以及时执行了。

  • iWebFusion:独立服务器月付57美元起/5个机房可选,10Gbps服务器月付149美元起

    iWebFusion(iWFHosting)在部落分享过很多次了,这是成立于2001年的老牌国外主机商H4Y旗下站点,提供的产品包括虚拟主机、VPS和独立服务器租用等等,其中VPS主机基于KVM架构,数据中心可选美国洛杉矶、北卡、本德、蒙蒂塞洛等。商家独立服务器可选5个不同机房,最低每月57美元起,而大流量10Gbps带宽服务器也仅149美元起。首先我们分享几款常规服务器配置信息,以下机器可选择5...

    优林70/月,西南高防地区最低70/月

    优林怎么样?优林好不好?优林 是一家国人VPS主机商,成立于2016年,主营国内外服务器产品。云服务器基于hyper-v和kvm虚拟架构,国内速度还不错。今天优林给我们带来促销的是国内西南地区高防云服务器!全部是独享带宽!续费同价!官方网站:https://www.idc857.com​地区CPU内存硬盘流量带宽防御价格购买地址德阳高防4核4g50G无限流量10M100G70元/月点击购买德阳高防...

    小欢互联19元/月起, 即日起至10月底 美国CERA 促销活动 美国/香港八折

    小欢互联成立于2019年10月,主打海外高性价比云服务器、CDN和虚拟主机服务。近期上线了自营美国CERA机房高速VPS,进行促销活动,为客户奉上美国/香港八折优惠码:Xxc1mtLB优惠码适用于美国CERA一区/二区以及香港一区/二区优惠时间:即日起至10月底优惠码可无限次使用,且续费同价!官网:https://idc.xh-ws.com购买地址:美国CERA一区:https://idc.xh-...

    queueuserworkitem为你推荐
    google地球打不开google earth打不开怎么办?解压程序软件怎么解压深圳公交车路线深圳公交线路最新qq空间代码qq空间都是有哪些免费代码!(要全部)免费开通黄钻能免费开通黄钻吗??快速美白好方法有什么变白的好方法arm开发板ARM开发板和树莓派有什么区别显卡温度多少正常显卡温度多少算正常?数码资源网有什么网站弄相片效果比较好的?qq空间打扮QQ空间怎么打扮如何打扮
    域名抢注工具 duniu 国内php空间 php空间推荐 100mbps 腾讯总部在哪 smtp虚拟服务器 英雄联盟台服官网 iki 深圳域名 电信主机托管 godaddy域名 hosts文件 asp简介 asp.net虚拟主机 rewrite规则 ddos防火墙 阿里云主机 国内云主机 租主机 更多