使用Tthreadmysql线程池数量查看类时怎么控制mysql线程池数量查看数量

TThread类 & Thread类是Delphi语言提供的线程类,该线程类可以完成大多数的线程操作
TThread类的属性 &&
&1.(1)FreeOnTerminate属性 &&&&&
&当线程终止时是否自动删除线程对象.默认值为T&&语法:property FreeOnTerminate: B &&
2 Priority属性 &&&& 指定线程的优先级. & property Priority: TTreadP && &&
3 ReturnValue属性 &&&&& 线程终止时,用该属性为其他线程传递一个返回值. &&
&4 Suspended属性 &&&& 指定线程是否处于挂起状态 &&
&5 Terminated &&&&& 线程运行晨,如果将属性为True时,线程终止 &
&6 ThreadID属性 &&&& 线程的惟一标识 &&
7 Handle属性 &&&& 线程句柄 & &
TThread类方法 &&&
&DoTerminate: 调用线程对象DoTerminate方法可以触发线程的OnTerminate事件 &&&
&Execute:线程的执行部分都写在该有方法中.必须实现的 &&&
&Resume:当线程对象处于暂停状态时,调用此方法可以恢复线程运行 &&
& Suspend:暂停线程 &&&
&Synchronize:线程同步 &&&
&Terminate:终止线程 &&&
&WaitFor:等待线程对象的终止,并返回线程对象的ReturnValue属性值 &&
unit Unit2;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtype
TMyThread = class(TThread)
procedure Run();
procedure Eoverride;
TfrmDemo = class(TForm)
ProgressBar1: TProgressB
Button1: TB
Button2: TB
Label1: TL
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
{ Private declarations }
{ Public declarations }
frmDemo: TfrmDimplementation{$R *.dfm}{ TMyThread }procedure TMyThread.Ebegin
inherited;
//线程同步
Synchronize(Run);end;procedure TMyThread.Rvar
with frmDemo do
for I := 0 to ProgressBar1.Max do
Label1.Caption := '工作线程运行中';
ProgressBar1.Position :=
Application.ProcessM
end;end;procedure TfrmDemo.Button1Click(Sender: TObject);var
for I := 0 to ProgressBar1.Max do
Label1.Caption := '主线程运行中';
ProgressBar1.Position :=
Application.ProcessM
end;end;procedure TfrmDemo.Button2Click(Sender: TObject);var
MyThread: TMyTbegin
MyThread := TMyThread.Create(false);
end;procedure TfrmDemo.FormCreate(Sender: TObject);begin
progressbar1.Max := 1000000;end;end.
阅读(...) 评论()随笔 - 2146&
文章 - 94&评论 - 11682&trackbacks - 253
多线程应该是编程工作者的基础技能, 但这个基础对我来讲的确有点难(起码昨天以前是这样).
开始本应该是一篇洋洋洒洒的文字, 不过我还是提倡先做起来, 在尝试中去理解.
先试试这个:
procedure TForm1.Button1Click(Sender: TObject);
for i := 0 to 500000 do
Canvas.TextOut(10, 10, IntToStr(i));
上面程序运行时, 我们的窗体基本是 "死" 的, 可以在你在程序运行期间拖动窗体试试...
Delphi 为我们提供了一个简单的办法(Application.ProcessMessages)来解决这个问题:
procedure TForm1.Button1Click(Sender: TObject);
for i := 0 to 500000 do
Canvas.TextOut(10, 10, IntToStr(i));
Application.ProcessM
这个 Application.ProcessM 一般用在比较费时的循环中, 它会检查并先处理消息队列中的其他消息.
但这算不上多线程, 譬如: 运行中你拖动窗体, 循环会暂停下来...
在使用多线程以前, 让我们先简单修改一下程序:
function MyFun: I
for i := 0 to 500000 do
Form1.Canvas.L
Form1.Canvas.TextOut(10, 10, IntToStr(i));
Form1.Canvas.U
Result := 0;
procedure TForm1.Button1Click(Sender: TObject);
细数上面程序的变化:
1、首先这还不是多线程的, 也会让窗体假 "死" 一会;
2、把执行代码写在了一个函数里, 但这个函数不属于 TForm1 的方法, 所以使用 Canvas 是必须冠以名称(Form1);
3、既然是个函数, (不管是否必要)都应该有返回值;
4、使用了 500001 次 Lock 和 Unlock.
Canvas.Lock 好比在说: Canvas(绘图表面)正忙着呢, 其他想用 Canvas 的等会;
Canvas.Unlock : 用完了, 解锁!
在 Canvas 中使用 Lock 和 Unlock 是个好习惯, 在不使用多线程的情况下这无所谓, 但保不准哪天程序会扩展为多线程的; 我们现在学习多线程, 当然应该用.
在 Delphi 中使用多线程有两种方法: 调用 API、使用 TThread 类; 使用 API 的代码更简单.
function MyFun(p: Pointer): I
for i := 0 to 500000 do
Form1.Canvas.L
Form1.Canvas.TextOut(10, 10, IntToStr(i));
Form1.Canvas.U
Result := 0;
procedure TForm1.Button1Click(Sender: TObject);
CreateThread(nil, 0, @MyFun, nil, 0, ID);
CreateThread 一个线程后, 算上原来的主线程, 这样程序就有两个线程、是标准的多线程了;
CreateThread 第三个参数是函数指针, 新线程建立后将立即执行该函数, 函数执行完毕, 系统将销毁此线程从而结束多线程的故事.
CreateThread 要使用的函数是系统级别的, 不能是某个类(譬如: TForm1)的方法, 并且有严格的格式(参数、返回值)要求, 不管你暂时是不是需要都必须按格式来;
因为是系统级调用, 还要缀上 stdcall, stdcall 是协调参数顺序的, 虽然这里只有一个参数没有顺序可言, 但这是使用系统函数的惯例.
CreateThread 还需要一个 var 参数来接受新建线程的 ID, 尽管暂时没用, 但这也是格式; 其他参数以后再说吧.
这样一个最简单的多线程程序就出来了, 咱们再用 TThread 类实现一次
TMyThread = class(TThread)
procedure E
procedure TMyThread.E
FreeOnTerminate := T {这可以让线程执行完毕后随即释放}
for i := 0 to 500000 do
Form1.Canvas.L
Form1.Canvas.TextOut(10, 10, IntToStr(i));
Form1.Canvas.U
procedure TForm1.Button1Click(Sender: TObject);
TMyThread.Create(False);
TThread 类有一个抽象方法(Execute), 因而是个抽象类, 抽象类只能继承使用, 上面是继承为 TMyThread.
继承 TThread 主要就是实现抽象方法 Execute(把我们的代码写在里面), 等我们的 TMyThread 实例化后, 首先就会执行 Execute 方法中的代码.
按常规我们一般这样去实例化:
procedure TForm1.Button1Click(Sender: TObject);
MyThread: TMyT
MyThread := TMyThread.Create(False);
因为 MyThread 变量在这里毫无用处(并且编译器还有提示), 所以不如直接写做 TMyThread.Create(False);
我们还可以轻松解决一个问题, 如果: TMyThread.Create(True) ?
这样线程建立后就不会立即调用 Execute, 可以在需要的时候再用 Resume 方法执行线程, 譬如:
procedure TForm1.Button1Click(Sender: TObject);
MyThread: TMyT
MyThread := TMyThread.Create(True);
MyThread.R
//可简化为:
procedure TForm1.Button1Click(Sender: TObject);
with TMyThread.Create(True) do R
使用 TThread 类时, Delphi 有提供的模板, 但用 IDE 写代码很方便, 我重写一遍录下来给大家看:
期间使用了 Ctrl+J、Shift+Ctrl+C、Ctrl+Alt+P 等快捷键.
重要的修正与补充:
在 TThread 类的例子中, 应该有这句: FreeOnTerminate := T (原来漏掉, 代码中已加上; 但动画加不上了).
先说它什么意思:
类 Create 了就要 F
但 TThread(的子类) 有特殊性, 很多时候我们不能确定新建的线程什么时候执行完(也就是什么时候该释放);
如果线程执行完毕自己知道释放就好了, 所以 TThread 给了一个布尔属性 FreeOnTerminate, 如果为 True, 线程执行完毕后就会自释放.
我怎么会忽略了这么重要的问题呢? 原因有二:
1、我一直在追求最精炼的代码;
2、我手头上不只一本书上介绍说: FreeOnTerminate 的默认值是 True(错误!), 经落实, 应该是 False, 起码在 Delphi 2007 和 2009 中是这样; 或许以前的某个版本和现在不一样.
阅读(...) 评论()2910人阅读
多线程(1)
一. &多线程要考虑的问题
前人总结出,一个线程安全的class应当满足的条件:
1. 从多个线程访问时,其表现出正确的行为,无论操作系统如何调度这些线程,无论这些线程的执行顺序如何交织。
2. 调用端代码无需额外的同步或其他协调动作
在写多线程程序时脑子里要有这样的意识,下面我总结了几条比较具体的注意事项。
使用多线程要考虑的问题:
1. 线程访问资源安全(线程同步问题),这个问题,可用Mutex封装临界区,我的里有介绍.
2. 线程退出安全(主线程结束前线程安全退出),可在主线程结束时,在对象析构里等待线程退出再析构.
3. 跨线程使用的对象的生命周期的控制,要保证对象(指针)不再被使用时才析构。为了安全,少费精力,还是用shared_ptr代替原始指针吧。shared_ptr是boost库的智能指针,现在已加入标准库中,用法不说了,说一下线程中使用注意事项吧。
shared_ptr的线程安全:
shared_ptr的线程安全级别与内建类型一样,多个线程同时对一个shared_ptr进行读操作时是安全的,多个线程同时对多个shared_ptr进行写操作时是安全的,其余都是未定义的。
shared_ptr作为函数参数:
因为拷贝shared_ptr是要修改引用计数的,所以拷贝shared_ptr比拷贝原始指针成本要高,多数情况下可以以reference to const方式传递,只需要在最外层的函数有个实体对象,以后都可以用reference to const来使用这个shared_ptr。
二. &一个封装好的线程类
下面我写了个线程封装类(windows平台),线程时使用它能少写一些代码~ &源码呈上:
#ifndef HBASE_HTHREAD_H__
#define HBASE_HTHREAD_H__
#include &Windows.h&
#ifdef Xxx_CALLBACK
#include &Core/Core.h&
/** 在类A中使用HThread类:
将HThread类的对象作为类A的成员.
Start函数,启动一个线程
WaitExit函数,在A的析构里调用,保证在主线程退出前线程退出.
注意:一个HThread类同时最多只能运行一个线程。
如果使用Callback封装unsigned (__stdcall * _start_address) (void *)函数,使用更灵活.
class HThread
HThread();
~HThread();
#ifdef Xxx_CALLBACK
Start(Xxx::Callback _cb);
Start(unsigned (__stdcall * _start_address) (void *), void * _arg_list);
WaitExit();
IsRunning();
IsOpen() const
{ return (NULL != handle_); }
GetHandle() const
{ return handle_; }
protected:
#ifdef Xxx_CALLBACK
static unsigned __stdcall ThreadRuntime(void* p);
HThread(const HThread&);
HThread& operator=(const HThread&);
#include &process.h&
#include &hthread.h&
HThread::HThread() : handle_(NULL)
HThread::~HThread()
// Wait() ?
#ifdef Xxx_CALLBACK
unsigned __stdcall HThread::ThreadRuntime(void* p)
Xxx::Callback *cb = (Xxx::Callback *)p;
bool HThread::Start(Xxx::Callback _cb)
Xxx::Callback *cb = new Xxx::Callback(_cb);
handle_ = (HANDLE)_beginthreadex(0, 0, &HThread::ThreadRuntime, cb, 0, NULL);
return (0 != handle_);
bool HThread::Start(unsigned (__stdcall * _start_address) (void *), void * _arg_list)
handle_ = (HANDLE)_beginthreadex(0, 0, _start_address, _arg_list, 0, NULL);
return (0 != handle_);
int HThread::WaitExit()
if(!IsOpen())
return -1;
if(!GetExitCodeThread(handle_, &exit))
return -1;
if(exit != STILL_ACTIVE)
out = (int)
if(WaitForSingleObject(handle_, INFINITE) != WAIT_OBJECT_0)
out = GetExitCodeThread(handle_, &exit) ? int(exit) : int(0);
bool HThread::IsRunning()
if(!IsOpen())
if(!GetExitCodeThread(handle_, &exit))
return (exit == STILL_ACTIVE)? true :
void HThread::Detach()
if(handle_) {
CloseHandle(handle_);
handle_ = 0;
三. 根据任务类型封装的线程类
在用线程处理问题时常常分两种情况:
A. 这个线程只做一件事,或循环做一件事情,做完这件事情之后就不再用它了,此时就要结束这个线程,称这种线程为单任务型。
B. 启动一个线程后,有个事情A需要在线程里完成,此时把任务A交给线程,没过多久又有个任务B要做,再把B交给这个线程去完成,也就是说这个线程能完成各种类型的任务,这种类型的线程称为多任务型,如果管理多个线程,就成线程池了。
单任务型适合用于耗时的重复性操作,比如上传1000张图片,这种线程为该任务而生,任务结束线程也就结束了。
多任务型线程长期活着,接各种耗时短的杂活,有时候会下载个文件,有时候数据库插入个图片。
说了这么多,看代码吧~
#ifndef MATERIAL_THREAD_H__
#define MATERIAL_THREAD_H__
#include &Windows.h&
#include &Core/Core.h&
#include &deque&
class TaskThreadBase
TaskThreadBase();
virtual ~TaskThreadBase();
virtual int WaitExit();
IsRunning();
IsOpen() const
{ return (NULL != handle_); }
GetHandle() const
{ return handle_; }
TaskThreadBase(const TaskThreadBase&);
TaskThreadBase& operator=(const TaskThreadBase&);
protected:
class TaskThread : public TaskThreadBase
TaskThread();
~TaskThread();
Start(Upp::Callback _cb);
Start(unsigned (__stdcall * _start_address) (void *), void * _arg_list);
protected:
static unsigned __stdcall ThreadRuntime(void* p);
class MutiTaskThread : public TaskThreadBase
struct Task
Task(Upp::Callback cb) : cb(cb) {}
MutiTaskThread();
~MutiTaskThread();
void SetMaxTaskCount(size_t task_count);
bool Start();
bool AddTask(Upp::Callback cb, bool priority = false);
virtual int WaitExit();
static unsigned __stdcall ThreadRuntime(void* p);
void Run();
void DoTask(const Task& task);
void RequestStop();
std::deque&Task&
max_task_count_;
Upp::Mutex
Upp::Semaphore
semaphore_;
#include &process.h&
#include &materialthread.h&
TaskThreadBase::TaskThreadBase() : handle_(NULL)
TaskThreadBase::~TaskThreadBase()
// Wait() ?
int TaskThreadBase::WaitExit()
if(!IsOpen())
return -1;
if(!GetExitCodeThread(handle_, &exit))
return -1;
if(exit != STILL_ACTIVE)
out = (int)
if(WaitForSingleObject(handle_, INFINITE) != WAIT_OBJECT_0)
out = GetExitCodeThread(handle_, &exit) ? int(exit) : int(0);
bool TaskThreadBase::IsRunning()
if(!IsOpen())
if(!GetExitCodeThread(handle_, &exit))
return (exit == STILL_ACTIVE)? true :
void TaskThreadBase::Detach()
if(handle_) {
CloseHandle(handle_);
handle_ = 0;
TaskThread::TaskThread()
TaskThread::~TaskThread()
unsigned __stdcall TaskThread::ThreadRuntime(void* p)
Upp::Callback *cb = (Upp::Callback *)p;
bool TaskThread::Start(Upp::Callback _cb)
Upp::Callback *cb = new Upp::Callback(_cb);
handle_ = (HANDLE)_beginthreadex(0, 0, &TaskThread::ThreadRuntime, cb, 0, NULL);
return (0 != handle_);
bool TaskThread::Start(unsigned (__stdcall * _start_address) (void *), void * _arg_list)
handle_ = (HANDLE)_beginthreadex(0, 0, _start_address, _arg_list, 0, NULL);
return (0 != handle_);
MutiTaskThread::MutiTaskThread() : max_task_count_(1), quit_(false)
MutiTaskThread::~MutiTaskThread()
void MutiTaskThread::SetMaxTaskCount(size_t task_count)
max_task_count_ = task_
bool MutiTaskThread::Start()
if (running_)
running_ =
handle_ = (HANDLE)_beginthreadex(0, 0, ThreadRuntime, this, 0, NULL);
return (0 != handle_);
unsigned __stdcall MutiTaskThread::ThreadRuntime(void* p)
MutiTaskThread* self = (MutiTaskThread*)p;
self -&Run();
void MutiTaskThread::RequestStop()
semaphore_.Release();
void MutiTaskThread::Run()
while(true)
bool empty =
Upp::Mutex::Lock lock(mutex_);
if (!tasks_.empty())
cur_task = tasks_.front();
if (quit_)
if (!empty) {
DoTask(cur_task);
Upp::Mutex::Lock lock(mutex_);
if (!tasks_.empty())
tasks_.pop_front();
semaphore_.Wait();
running_ =
bool MutiTaskThread::AddTask(Upp::Callback cb, bool priority /*= false*/)
bool ret =
Upp::Mutex::Lock lock(mutex_);
Task task(cb);
size_t n = tasks_.size();
if (n & max_task_count_) {
if (priority)
tasks_.push_front(task);
tasks_.push_back(task);
if (0 == n)
semaphore_.Release();
void MutiTaskThread::DoTask(const Task& task)
task.cb();
int MutiTaskThread::WaitExit()
RequestStop();
return TaskThreadBase::WaitExit();
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:203490次
积分:2003
积分:2003
排名:第14604名
原创:39篇
评论:41条
(2)(1)(2)(1)(1)(1)(1)(2)(1)(9)(1)(1)(1)(1)(2)(1)(2)(2)(6)(1)多核时代下的多线程编程----帮大家读懂TThread类
多核时代下的多线程编程----帮大家读懂TThread类
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。使用Tthread线程类时如何控制线程数量?-中国学网-中国IT综合门户网站-提供健康,养生,留学,移民,创业,汽车等信息
使用Tthread线程类时如何控制线程数量?
来源:互联网 更新时间: 5:28:51 责任编辑:王亮字体:
用户提出问题:使用Tthread线程类时如何控制线程数量?,具体如下:
通过互联网整理获得以下解决方法:=================1楼=====================
LZ的方法可行
=================2楼=====================
可行的,不要觉得线程池多磨高深,你认为控制数量,不计数还能怎样
=================3楼=====================
LZ表谦虚了,代码可以做范例了
=================4楼=====================
-.-&总不能大家都是这样来控制线程数的吧
主要是&判断线程数然后循环那地方感觉不正规.
=================5楼=====================
其实不要把线程池想得多复杂,最简单的就是一个封装了用于记录线程的LIST的类,再加点方法属性这样
=================6楼=====================
线程数量这样控制不妥吧,如果无限请求创建,你这样就创建了无限多个线程,只是真正运转的只有9个线程而以,本质上线程数量仍然没有控制住。
应该是通过&thread,写一个的类方法&class&function&CreateMyThread():来创建,将&构造&函数&私有化,这样,如果到上限了就不与分配,或者说维护一个任务队列,空下来的线程到队列中取任务,也省去了重复创建线程的资源消耗。
=================7楼=====================
这写法确实是有问题!&像6楼所说你可以维护一个线程队列(其实就是线程池的概念).不要搞那复杂的,只要简单一点的就可以。
1、定义一个结构体
&&&ThreadList&=&Record
&&&&&ThreadHwndList:TS&//线程句柄列表(可以方便的控件线程)
&&&&&&ThreadCount:I&&&&&//线程总数量
&&&&&&...&//如果有其他需要记录的继续写
2、创建线程时判断ThreadCount的数量。
3、创建时ThreadCount&+&1;&结束时ThreadCount&-1;
这是一个最简单的东西了。要真正使用还需要好好考虑一下,方法应该很多。
=================8楼=====================
感谢LS上的&顶起来&&希望更多人看到
=================9楼=====================
看看线程池的相关资料
=================10楼=====================
Sockets单元搜索ThreadPool
=================11楼=====================
拖久了&现在结贴
如果您还有更好的解决方法,请在最下面评论中留下您的解决方法
相关文章:
<a href="/cse/search?q=<inputclass="s-btn"type="submit"text="<inputclass="s-btn"type="submit"text="<buttonhidefocusclass="s-btnjs-ask-btn"text="我要提问
<a href="/cse/search?q=}

我要回帖

更多关于 linux查看线程数量 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信