C#多线程--获取当前线程ID
2014-02-10 11:23
267 查看
【文章标题】: 乱涂C#多线程02
【文章作者】: 有酒醉
【作者邮箱】: wuqr32@sina.com
【下载地址】: 自己搜索下载
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
采用线程池线程执行任务我们无法直接控制线程.有时我们想直接控制线程的行为,那么我们可以创建非线程池线程.
编译运行:
D:\>csc ThreadDemo.cs
Microsoft (R) Visual C# .NET 编译器版本 7.10.6001.4
用于 Microsoft (R) .NET Framework 版本 1.1.4322
版权所有 (C) Microsoft Corporation 2001-2002。保留所有权利。
D:\>ThreadDemo
Hello ThreadProc
Priority:Normal
ThreadState:WaitSleepJoin
Hello Main
Hello Main
Hello Main
Hello Main
Hello Main
Hello ThreadProc
Hello ThreadProc
Hello ThreadProc
Hello ThreadProc
前台线程和后台线程:线程池线程都是后台线程,一般线程创建时默认为前台线程,可以通过Thread.IsBackground属性进行更改.一旦程序中不再有前台线程,Windows将终止该程序.
我们先来看看前台线程
D:\>csc ThreadDemo.cs
D:\>ThreadDemo
Hello ThreadProc
Hello ThreadProc
Hello ThreadProc
Hello ThreadProc
Hello ThreadProc
奇怪!程序并未调用Thread.Join()方法,自定义线程也一样执行完.正常情况下t.Start()执行完后Main也就终结了,整个程序应该退出才是!
接下来我们测试一下后台线程,将下面代码的注释去掉:
//t.IsBackground = true;
重新运行看效果:
D:\>csc ThreadDemo.cs
D:\>ThreadDemo
D:\>
什么结果也没有!!换句话说,只要有一个前台线程,不管Main上代码是否都已经执行,它也将等待其他前台线程执行完毕才退出.如果Main上的代码都已执行同时不存在前台线程,那么程序自动退出.
同样还有一个问题存在,我们更改一下上面的程序:
编译运行:
D:\>csc ThreadDemo.cs
Microsoft (R) Visual C# .NET 编译器版本 7.10.6001.4
用于 Microsoft (R) .NET Framework 版本 1.1.4322
版权所有 (C) Microsoft Corporation 2001-2002。保留所有权利。
D:\>ThreadDemo
the t of thread is Background:False
D:\>
问题1:如果按我们刚才的理解,t是前台线程,Main理应等待线程t完全执行完毕才是,但是结果却什么也没输出!这是什么缘故?暂时还没研究出答案,待我们深入探讨之后在回头看这个问题
非托管线程是通过线程ID来标识的,托管线程则通过散列代码(Thread.GetHashCode())或名称(Thread.Name)来标识.获取当前线程ID采用AppDomain.GetCurrentThreadId().
示例-获取线程ID
编译运行:
D:\>cl /clr T.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 13.10.3077 for .NET Framework
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.
T.cpp
Microsoft (R) Incremental Linker Version 7.10.3077
Copyright (C) Microsoft Corporation. All rights reserved.
/out:T.exe
T.obj
D:\>T
Thread id:1800
D:\>
注意!如果将main更改为:
#pragma unmanaged
int main()
{
ThreadDelagate *td = new ThreadDelagate;
td->Start();
}
编译将得到如下错误:
error C3821: “ThreadDelagate” : 托管类型不能用于非托管函数
error C3169: “td” : 在非托管函数内不能声明托管对象或 __gc 指针
error C3821: “ThreadDelagate” : 托管类型不能用于非托管函数
error C3175: “ThreadDelagate::ThreadDelagate” : 不能从非托管函数“main”调用托管类型的方法
error C3821: “td” : 托管类型不能用于非托管函数
error C3175: “ThreadDelagate::Start” : 不能从非托管函数“main”调用托管类型的方法
原因我就不多讲.很明朗!因此,如果要操纵托管线程ID,需先把它保存起来,然后在非托管代码中进行应用.
示例-枚举非托管线程(ProcessThread表示操作系统进程线程)
编译运行:
D:\>ProcessThreadDemo
h
7 threads in process
ID:3700,State:Running,Priority:Normal
ID:1076,State:Wait,Priority:Normal
ID:452,State:Wait,Priority:Highest
ID:2292,State:Wait,Priority:Normal
ID:3872,State:Wait,Priority:Normal
ID:2952,State:Wait,Priority:Normal
ID:996,State:Wait,Priority:Normal
通过枚举的方式我们发现该程序存在7个线程,但是在运行初期,我们通过任务管理器发现它的线程数才3个!这是什么原因呢?原来在枚举进程线程的操作实际上会使CLR创建更多的线程,用以执行此枚举操作!!
<续>
--------------------------------------------------------------------------------
【版权声明】: 本文原创于泉州软件基地, 转载请注明作者并保持文章的完整, 谢谢!
【文章作者】: 有酒醉
【作者邮箱】: wuqr32@sina.com
【下载地址】: 自己搜索下载
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
采用线程池线程执行任务我们无法直接控制线程.有时我们想直接控制线程的行为,那么我们可以创建非线程池线程.
// ThreadDemo.cs // Author by Yzl using System; using System.Threading; public class ThreadDemo { public static void Main(string[] args) { Thread t = new Thread(new ThreadStart(ThreadProc)); t.Start(); Console.WriteLine("Priority:" + t.Priority); Console.WriteLine("ThreadState:" + t.ThreadState); for (int i = 0; i < 5; i ++) { Console.WriteLine("Hello Main"); Thread.Sleep(100); } } private static void ThreadProc() { for (int i = 0;i < 5; i ++) { Console.WriteLine("Hello ThreadProc"); Thread.Sleep(500); } } }
编译运行:
D:\>csc ThreadDemo.cs
Microsoft (R) Visual C# .NET 编译器版本 7.10.6001.4
用于 Microsoft (R) .NET Framework 版本 1.1.4322
版权所有 (C) Microsoft Corporation 2001-2002。保留所有权利。
D:\>ThreadDemo
Hello ThreadProc
Priority:Normal
ThreadState:WaitSleepJoin
Hello Main
Hello Main
Hello Main
Hello Main
Hello Main
Hello ThreadProc
Hello ThreadProc
Hello ThreadProc
Hello ThreadProc
前台线程和后台线程:线程池线程都是后台线程,一般线程创建时默认为前台线程,可以通过Thread.IsBackground属性进行更改.一旦程序中不再有前台线程,Windows将终止该程序.
我们先来看看前台线程
// ThreadDemo.cs // Author by Yzl using System; using System.Threading; public class ThreadDemo { public static void Main(string[] args) { Thread t = new Thread(new ThreadStart(ThreadProc)); t.Name = "CustomThread"; //t.IsBackground = true; t.Start(); } private static void ThreadProc() { for (int i = 0;i < 5; i ++) { Console.WriteLine("Hello ThreadProc"); Thread.Sleep(800); } } }
D:\>csc ThreadDemo.cs
D:\>ThreadDemo
Hello ThreadProc
Hello ThreadProc
Hello ThreadProc
Hello ThreadProc
Hello ThreadProc
奇怪!程序并未调用Thread.Join()方法,自定义线程也一样执行完.正常情况下t.Start()执行完后Main也就终结了,整个程序应该退出才是!
接下来我们测试一下后台线程,将下面代码的注释去掉:
//t.IsBackground = true;
重新运行看效果:
D:\>csc ThreadDemo.cs
D:\>ThreadDemo
D:\>
什么结果也没有!!换句话说,只要有一个前台线程,不管Main上代码是否都已经执行,它也将等待其他前台线程执行完毕才退出.如果Main上的代码都已执行同时不存在前台线程,那么程序自动退出.
同样还有一个问题存在,我们更改一下上面的程序:
// ThreadDemo.cs // Author by Yzl using System; using System.Threading; public class ThreadDemo { public static void Main(string[] args) { Thread t = new Thread(new ThreadStart(ThreadProc)); t.Name = "CustomThread"; Thread.CurrentThread.IsBackground = true; // 注意!设置主线程为后台线程! Console.WriteLine("the t of thread is Background:" + t.IsBackground); // 注意! t.Start(); } private static void ThreadProc() { for (int i = 0;i < 5; i ++) { Console.WriteLine("Hello ThreadProc"); Thread.Sleep(800); } } }
编译运行:
D:\>csc ThreadDemo.cs
Microsoft (R) Visual C# .NET 编译器版本 7.10.6001.4
用于 Microsoft (R) .NET Framework 版本 1.1.4322
版权所有 (C) Microsoft Corporation 2001-2002。保留所有权利。
D:\>ThreadDemo
the t of thread is Background:False
D:\>
问题1:如果按我们刚才的理解,t是前台线程,Main理应等待线程t完全执行完毕才是,但是结果却什么也没输出!这是什么缘故?暂时还没研究出答案,待我们深入探讨之后在回头看这个问题
非托管线程是通过线程ID来标识的,托管线程则通过散列代码(Thread.GetHashCode())或名称(Thread.Name)来标识.获取当前线程ID采用AppDomain.GetCurrentThreadId().
示例-获取线程ID
// T.cpp // Author by Yzl #include < stdio.h > #using < mscorlib.dll > using namespace System::Threading; #pragma managed __gc class ThreadDelagate { public: void Start() { ThreadStart *ts = new ThreadStart(this,ThreadProc); Thread* myThread = new Thread(ts); myThread->Start(); } private: void ThreadProc() { printf("Thread id:%d",System::AppDomain::GetCurrentThreadId()); } }; #pragma managed int main() { ThreadDelagate *td = new ThreadDelagate; td->Start(); }
编译运行:
D:\>cl /clr T.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 13.10.3077 for .NET Framework
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.
T.cpp
Microsoft (R) Incremental Linker Version 7.10.3077
Copyright (C) Microsoft Corporation. All rights reserved.
/out:T.exe
T.obj
D:\>T
Thread id:1800
D:\>
注意!如果将main更改为:
#pragma unmanaged
int main()
{
ThreadDelagate *td = new ThreadDelagate;
td->Start();
}
编译将得到如下错误:
error C3821: “ThreadDelagate” : 托管类型不能用于非托管函数
error C3169: “td” : 在非托管函数内不能声明托管对象或 __gc 指针
error C3821: “ThreadDelagate” : 托管类型不能用于非托管函数
error C3175: “ThreadDelagate::ThreadDelagate” : 不能从非托管函数“main”调用托管类型的方法
error C3821: “td” : 托管类型不能用于非托管函数
error C3175: “ThreadDelagate::Start” : 不能从非托管函数“main”调用托管类型的方法
原因我就不多讲.很明朗!因此,如果要操纵托管线程ID,需先把它保存起来,然后在非托管代码中进行应用.
示例-枚举非托管线程(ProcessThread表示操作系统进程线程)
// ProcessThreadDemo.cs // Author by Yzl using System; using System.Diagnostics; public class ProcessThreadDemo { public static void Main(string[] args) { Console.ReadLine(); ProcessThreadCollection ptCollection = Process.GetCurrentProcess().Threads; Console.WriteLine("{0} threads in process",ptCollection.Count); foreach (ProcessThread pt in ptCollection) { Console.WriteLine("ID:{0},State:{1},Priority:{2}",pt.Id,pt.ThreadState,pt.PriorityLevel); } } }
编译运行:
D:\>ProcessThreadDemo
h
7 threads in process
ID:3700,State:Running,Priority:Normal
ID:1076,State:Wait,Priority:Normal
ID:452,State:Wait,Priority:Highest
ID:2292,State:Wait,Priority:Normal
ID:3872,State:Wait,Priority:Normal
ID:2952,State:Wait,Priority:Normal
ID:996,State:Wait,Priority:Normal
通过枚举的方式我们发现该程序存在7个线程,但是在运行初期,我们通过任务管理器发现它的线程数才3个!这是什么原因呢?原来在枚举进程线程的操作实际上会使CLR创建更多的线程,用以执行此枚举操作!!
<续>
--------------------------------------------------------------------------------
【版权声明】: 本文原创于泉州软件基地, 转载请注明作者并保持文章的完整, 谢谢!
相关文章推荐
- java获取本机IP,系统随机分配端口号,获取当前线程ID
- 获取当前进程/线程的ID、句柄和内核地址
- Linux下多线程编程__线程的创建pthread_create与退出pthread_exit,等待当前线程退出pthread_join,获取线程ID pthread_self
- 获取当前进程/线程的ID、句柄和内核地址
- 获取当前进程/线程的ID、句柄和内核地址
- 获取当前进程ID和子线程的线程ID
- 获取当前线程,线程id,设置优先级等函数接口
- 如何在Windows和Linux下获取当前线程的ID号
- MFC 获取当前线程的ID的问题
- QT 获取当前线程ID
- 获取当前线程的id号 gettid()
- 获取当前线程ID [NSThread currentThread]
- jdbc插入一条记录后,马上获取到当前记录的id,以方便对插入的当前记录进行更多的操作
- WPF 获取ListView中列添加LinkButton按钮,点击按钮的当前行的ID值
- 获取线程ID
- .net C# 中 thread 开启线程之后获取当前线程的信息
- MSSQL获取当前插入的ID号及在高并发的时候处理方式
- 获取指定进程所有线程的当前执行模块
- linux 获取线程ID的方法
- 第75篇一对多之合并开关声音按钮及获取当前按钮id及一个按钮控制两个函数