线程1.docx
- 文档编号:9215322
- 上传时间:2023-05-17
- 格式:DOCX
- 页数:20
- 大小:105.03KB
线程1.docx
《线程1.docx》由会员分享,可在线阅读,更多相关《线程1.docx(20页珍藏版)》请在冰点文库上搜索。
线程1
多线程学习笔记第一篇
1.多线程
(1)进程(Process):
是WIndows系统中的一个基本概念,它包含着一个运行程序所需要的资源,进程之间是相对独立的,一个进程无法直接访问另一个进程的数据(除非利用分布式计算方法),一个进程运行的失败也不会影响其他进程的运行,windows系统就是利用进程把工作划分为多个独立的区域,进程可以理解为一个程序的基本边界。
1)要解决的问题:
为了使程序能够并发执行(要并发处理就要隔离进程,使进程独立,即每个进程有属于自己的数据段,程序段,进程控制块)
2)进程是隔离不同应用程序的一种资源
3)进程Demo,代码如下:
staticvoidMain(string[]args)
{
//操作进程:
GetCurrentProcess读取当前进程
Console.WriteLine(Process.GetCurrentProcess());
//获取操作系统中的所有进程
varprocess=Process.GetProcesses();
foreach(variteminprocess)
{
//输出所有操作系统的名称
Console.WriteLine(item.ProcessName);
}
//开启一个应用程序的进程
Process.Start("iexplore.exe","
varp=Process.Start("notepad.exe");
//杀掉一个线程
Thread.Sleep(3000);
p.Kill();
}
(2)线程:
线程就是一个代码段的执行流
1)是Windows任务调度的最小单位,线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针,程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。
2)解决问题:
进程是一个资源的拥有者,因为在进程的创建,撤销和切换的过程中,系统必须为自付出比较大的开销,限制了并发程序的进一步提高
3)一个进程可以有多个线程
4)CPU的核心切换的是线程
5)操作系统:
一个CPU同一时间只能执行一个线程,多核,
6)操作系统切换线程的时候需要将线程的资源,状态都要保存起来。
7)线程创建的时候需要线程的控制块(1M),线程栈,线程寄存器。
(3)托管代码和非托管代码的区别
(4)线程Demo,创建一个控制台应用程序,代码如下:
ViewCode?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
namespaceThreadDemo
{
//当前这个程序的代码是执行在主线程上面的
classProgram
{
staticvoidMain(string[]args)
{
//打印出当前主线程的信息
ThreadcurrentThread=Thread.CurrentThread;
//打印出主线程的ID,ManagedThreadId是托管线程的一个唯一编号
Console.WriteLine("当前默认的主线程的ID是"+currentThread.ManagedThreadId);
//创建一个线程,传递一个ThreadStart参数,这个参数转到定义可以看到是一个委托
//创建一个线程对象,并没有真正的分配线程
ThreadthreadDemo=newThread(ThreadDemoMethod);
//只有调用此方法的时候,才是真正的告诉操作系统线程准备好,请操作系统分配线程并且执行
threadDemo.Start(); //启动线程来执行
Console.WriteLine("主线程执行结束");
Console.ReadKey();
}
staticvoidThreadDemoMethod()
{
Console.WriteLine("另一个线程正在执行,线程的ID是{0}",Thread.CurrentThread.ManagedThreadId);
}
}
}
这段代码的执行结果是:
当前默认的主线程的ID是1
主线程执行结束
另一个线程正在执行,线程的ID是3
(5)应用程序域
1)它提供安全而通用的处理单元,公共语言运行库(CLR)可以使用它来提供应用程序之间的隔离。
您可以在具有同等隔离级别(存在于单独的进程中)的单个进程中运行几个应用程序域,而不会造成进程间调用或者进程间切换等方面的额外开销,在一个进程内运行多个应用程序的能力显著增强了服务器的可伸缩性
2)应用程序域里面有内存分配的堆,也提供了一种代码安全的边界(两个应用程序域之间的代码是相互隔离的),提供了异常的处理
3)一个应用程序域可以跑多个线程
4)一个线程同一时间只能运行在一个应用程序域中,但是一个应用程序域可以同时拥有多个线程
5)应用程序域Demo
staticvoidMain(string[]args)
{
//打印当前应用程序域
Console.WriteLine(AppDomain.CurrentDomain.FriendlyName);
//创建应用程序域
AppDomaindomainDemo=AppDomain.CreateDomain("韩迎龙");
//让当前应用程序域启动执行一个exe程序(可以包含执行一个exe,但是可以有多个程序集dll)
//第一步:
将其他项目中的exe文件和pdf文件拷贝一份放到我们这个项目下面
//第二步:
将上面拷贝进来的exe文件右键属性,修改复制到输出目录为始终复制
domainDemo.ExecuteAssembly("摇奖机.exe");
}
6)执行结果,如图所示:
(6)简单线程详细说明
1)线程的调度是由操作系统来操作的,我们的操作只是建议
2)threadDemo.IsBackground=true;
->设置当前线程的一个类型,默认是前台线程
->true代表设置一个后台线程,当前台线程都关闭之后,当前进程就直接关闭了
->false代表设置一个前台线程,
3)线程设置Demo
ViewCode?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
classProgram
{
staticvoidMain(string[]args)
{
ThreadthreadDemo=newThread(DemoThreadMethod);
//设置当前线程的优先级,只是建议操作系统,给我当前的这个线程,优先级高点
threadDemo.Priority=ThreadPriority.Highest;
//如果设置成前台线程,那么就必须当前线程执行完毕之后,整个进程才会推出
threadDemo.IsBackground=true;
threadDemo.Start();
Thread.Sleep(3000);
//关闭线程
//threadDemo.Abort();
//将当前执行此代码的线程阻塞,等待线程执行完毕
threadDemo.Join(1000);
//给线程起一个名字
threadDemo.Name="线程";
Console.WriteLine("主线程执行完毕");
}
staticvoidDemoThreadMethod()
{
while(true)
{
Console.WriteLine(DateTime.Now.ToString());
}
}
}
(7)带参数的线程说明
1)ParameterizedThreadStart执行方法
->查看Reflect:
publicdelegatevoidParameterizedThreadStart(objectobj);
2)线程的委托都是没有返回值的,因为我们不知道线程什么时候结束
3)带参数的线程Demo
classProgram
{
staticvoidMain(string[]args)
{
//启动一个带参数的线程
ThreadthreadDemo=newThread(DemoParamets);
//给线程指定的方法传递参数
//可以传递数组
threadDemo.Start("韩迎龙");
Thread.Sleep(2000);
Console.ReadKey();
}
staticvoidDemoParamets(objectdata)
{
Console.WriteLine(data.ToString());
}
}
4)将上面这段代码在Reflect中查看代码:
如图所示:
2.线程中如何访问控件
(1)新建一个Winform应用程序,起名为:
MultiThread,给这个新建的WinForm窗体添加一个文本框控件和一个Button按钮
(2)Demo代码
ViewCode?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
publicpartialclassForm1:
Form
{
publicForm1()
{
InitializeComponent();
//如果不写的话会报这个错误:
线程间操作无效:
从不是创建控件“txtMSg”的线程访问它。
//还有一种方式解决将在下面说到
Control.CheckForIllegalCrossThreadCalls=false;
}
privatevoidbtnThread_Click(objectsender,EventArgse)
{
//这是一种写法
//newThread(()=>
//{
// txtMSg.Text=DateTime.Now.ToString();
//}).Start();
//第二种说法
Threadthread=newThread(ChangeTxt);
thread.Start();
}
publicvoidChangeTxt()
{
txtMSg.Text=DateTime.Now.ToString();
}
}
3.使用委托实现两个界面之间数据的交互案例
(1)新建一个Winform程序,将Form1窗体作为主窗体,在新建一个窗体作为子窗体,给父窗体添加一个Button和一个TextBox控件。
给子窗体中添加一个Button控件和一个TextBox控件,项目样式在后面有截图:
ViewCode?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
(2)主窗体中的代码如下:
publicpartialclassForm1:
Form
{
publicForm1()
{
InitializeComponent();
//如果不写的话会报这个错误:
线程间操作无效:
从不是创建控件“txtMSg”的线程访问它。
//还有一种方式解决将在下面说到
Control.CheckForIllegalCrossThreadCalls=false;
}
privatevoidbtnThread_Click(objectsender,EventArgse)
{
while(true)
{
Threadthread=newThread(ChangeTxt);
thread.Start();
}
}
publicvoidChangeTxt()
{
txtMSg.Text=DateTime.Now.ToString();
}
privatevoidbtnStart_Click(objectsender,EventArgse)
{
//使用委托实现
FrmChildfrm=newFrmChild();
//把当前主窗体的应用添加到this中
frm.ParentFrm=this;
frm.AfterTxtChange=newSetTextDel(SetText);
frm.Show();
}
//添加一个方法给主窗体的控件赋值
publicvoidSetText(stringstr)
{
txtMSg.Text=str;
}
}
(3)子窗体中的代码如下:
//使用委托实现这个功能
publicdelegatevoidSetTextDel(stringstr);
publicpartialclassFrmChild:
Form
{
//定义了一个父窗体的变量
publicForm1ParentFrm;
//定义一个委托类的实例
publicSetTextDelAfterTxtChange;
publicFrmChild()
{
InitializeComponent();
}
privatevoidbtnParent_Click(objectsender,EventArgse)
{
stringchildtxt=txtChildMsg.Text;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 线程