C# 线程、任务和同步

1,线程概述
线程是程序汇中独立的指令流。线程有一个优先级,实际上正在处理的程序的位置计数器,一个存储其局部变量的栈。每个线程都有自己的栈。但应用程序的内存和堆由一个进程的所有线程共享。
进程包含资源,如windows句柄,文件句柄或其他内核对象。每个进程都分配了虚拟内存。一个进程至少包含一个线程。操作系统会调度线程。

总结:
同步代码区域(代码块):lock,  Monitor, SpinLock,
Mutex,WaitHandle,Semaphore,EventWaitHandle,AutoRestEvent/ManualResetEvent.
Barrier,
ReadWriterLock(Slim)
多线程变量同步:InterLocked,

进程间同步:
Mutex, Semaphore,

2,异步委托:
创建线程的一种简单方式是定义一个委托,并异步调用它。委托时方法类型安全的引用。Delegate类还支持异步调用委托,在后头创建一个执行任务的线程。
  委托使用线程池来完成异步调用。
  public
delegate int TakesAWhileDelegate(int data, int ms);
2.1投票:
  IAsyncResult
ar=al.BeginInvoke(1,3000, null, null);
      int
result=dl.EndInvoke(ar);
2.2 等待句柄  (WaitHandle)


 1     class Program
2 {
3 public delegate int TakesAWhileDelegate(int data, int ms);
4 static int TakesAWhile(int data, int ms)
5 {
6 Console.WriteLine("TakesAWhile started");
7 Thread.Sleep(ms);
8 Console.WriteLine("TakesAWhile completed");
9 return ++data;
10 }
11 private static void Main(string[] args)
12 {
13 Console.WriteLine("Main Begin.");
14 TakesAWhileDelegate dl = TakesAWhile;
15 IAsyncResult ar = dl.BeginInvoke(2, 3000, null, null);
16
17 //ar.IsCompleted
18 //ar.AsyncWaitHandle.WaitOne(50)
19
20 dl.EndInvoke(ar);
21 Console.WriteLine("Main() end.");
22 Console.ReadLine();
23 }
24 }

投票(ar.IsCompleted)
或者等待句柄(ar.AsyncWaitHandle.WaitOne(50, false)

2.3 异步回调 (dl.BeginInvoke(1,3000, TakesAWhileCompleted, dl)
)
传入一个回调函数委托,来异步执行。

 1     class Program
2 {
3 public delegate int TakesAWhileDelegate(int data, int ms);
4 static int TakesAWhile(int data, int ms)
5 {
6 Console.WriteLine("TakesAWhile started");
7 Thread.Sleep(ms);
8 Console.WriteLine("TakesAWhile completed");
9 return ++data;
10 }
11 private static void Main(string[] args)
12 {
13 Console.WriteLine("Main Begin.");
14 TakesAWhileDelegate dl = TakesAWhile;
15 dl.BeginInvoke(2, 3000, ar =>
16 {
17 if (ar == null)
18 throw new ArgumentNullException("ar");
19 TakesAWhileDelegate dl1 = ar.AsyncState as TakesAWhileDelegate;
20 Trace.Assert(dl1 != null, "Invalid object type");
21 int result = dl1.EndInvoke(ar);
22 Console.WriteLine("result: {0}", result);
23 }, null);
24
25 Console.WriteLine("Main() end.");
26 Console.ReadLine();
27 }
28 }

回调方法

3,Thread类
3.1
给线程传递数据
  1,使用带ParameterizedThreadStart委托参数的Thread构造函数。2,创建自定义类,把线程的方法定位实例方法,这样就可以初始化实例的数据,之后启动线程。
3.2
后台线程:
  只要有一个前台线程在运行,应用程序的进程就在运行。如果多个前台线程在运行,而Main()方法结束了,应用程序的进程依然是激活的,直到所有前台线程完成其任务为止。
  


        private static void Main(string[] args)
{
var t1 = new Thread(ThreadMain) {Name = "MyNewThread", IsBackground = false};
t1.Start();
Console.WriteLine("Main Thread ending now.");

}

static void ThreadMain()
{
Console.WriteLine("Thread {0} started", Thread.CurrentThread.Name);
Thread.Sleep(3000);
Console.WriteLine("Thread {0} Completed",Thread.CurrentThread.Name);
}

前台线程示例

3.3 线程的优先级

4 线程池

5,任务
5.1 启动任务:
  


启动任务代码

            TaskFactory tf = new TaskFactory();
Task t1 = tf.StartNew(TaskMethod);

Task t2 = Task.Factory.StartNew(TaskMethod);

Task t3 = new Task(TaskMethod);
t3.Start();

5.2 连续的任务
Task t1=new Task(DoOnFirst);
Task
t2=t1.ContinueWith(DoOnSecond);

5.3任务层次结构

6 Parallel

Parallel.For
Parallel.ForEach()
Parallel.Invoke(fun1,fun2);


 1         private static void Main(string[] args)
2 {
3 Parallel.Invoke(TaskMethod1,TaskMethod2);
4
5 Console.ReadLine();
6 }
7
8 static void TaskMethod1()
9 {
10 Console.WriteLine("1running in a task.");
11 Console.WriteLine("Task id: {0}", Task.CurrentId);
12 }
13 static void TaskMethod2()
14 {
15 Console.WriteLine("2running in a task.");
16 Console.WriteLine("Task id: {0}", Task.CurrentId);
17 }

Parallel.Invoke Code

7. 取消架构

8, 线程问题:  争用条件和死锁
8.1 争用条件:


 1         public class StateObject
2 {
3 private int state = 5;
4
5 public void ChangeState(int loop)
6 {
7 lock (this)
8 {
9 if (state == 5)
10 {
11 state++;
12 Trace.Assert(state == 6, "Race condition ocurred after " + loop + " loops " + Task.CurrentId);
13 if (loop % 1000000 == 0)
14 {
15 Console.WriteLine("after " + loop + " loops " + Task.CurrentId);
16 }
17 }
18 state = 5;
19 }
20
21 }
22 }
23
24 public class SampleTask
25 {
26 public void RaceCondition(object o)
27 {
28 Trace.Assert(o is StateObject, "o must be of type StateObject.");
29 StateObject state = o as StateObject;
30 int i = 0;
31 while (true)
32 {
33 state.ChangeState(i++);
34 }
35 }
36 }
37
38 public class SampleThread
39 {
40 public SampleThread(StateObject s1, StateObject s2)
41 {
42 this.s1 = s1;
43 this.s2 = s2;
44 }
45
46 private StateObject s1;
47 private StateObject s2;
48
49 public void Deadlock1()
50 {
51 int i = 0;
52 while (true)
53 {
54 lock (s1)
55 {
56 lock (s2)
57 {
58 s1.ChangeState(i);
59 s2.ChangeState(i++);
60 Console.WriteLine("still running, {0}", i);
61
62 }
63 }
64 //Thread.Yield();
65 }
66 }
67 public void Deadlock2()
68 {
69 int i = 0;
70 while (true)
71 {
72 lock (s2)
73 {
74 lock (s1)
75 {
76 s1.ChangeState(i);
77 s2.ChangeState(i++);
78 Console.WriteLine("still running, {0}", i);
79
80 }
81 }
82 //Thread.Yield();
83 }
84 }
85 }
86
87 private static void Main(string[] args)
88 {
89 var state1 = new StateObject();
90 var state2 = new StateObject();
91
92 SampleThread st = new SampleThread(state1, state2);
93
94 Task.Factory.StartNew(st.Deadlock1);
95 Task.Factory.StartNew(st.Deadlock2);
96
97 Console.ReadLine();
98 }

死锁演示代码

9, 同步
9.1 Lock
语句
栈是线程独立的,但不是私有的。所有线程的栈内所有内容,都可以被其他线程访问。
为什么不用 lock(this)
?

因为这通常超出我们的控制,因为其他人也有可能lock这个对象。一个私有的对象是更好的选择。避免lock一个公开类型,或者超出你代码的控制的实例。
Tips:可以提供线程安全的原子操作。


 1     class Program
2 {
3 public class SharedState
4 {
5 public int State { get; set; }
6 }
7
8 public class Job
9 {
10 private SharedState sharedState;
11
12 public Job(SharedState sharedState)
13 {
14 this.sharedState = sharedState;
15 }
16
17 public void DoTheJob()
18 {
19 for (int i = 0; i < 50000; i++)
20 {
21 sharedState.State +=1;
22 }
23 }
24 }
25
26 private static void Main(string[] args)
27 {
28 int numTasks = 20
29 ;
30 var state = new SharedState();
31 var tasks = new Task[numTasks];
32 for (int j = 0; j < 5; j++)
33 {
34 state.State = 0;
35 for (int i = 0; i < numTasks; i++)
36 {
37 tasks[i] = new Task(new Job(state).DoTheJob);
38 tasks[i].Start();
39
40 }
41
42 for (int i = 0; i < numTasks; i++)
43 {
44 tasks[i].Wait();
45
46 }
47 Console.WriteLine("summarized {0}", state.State);
48 }
49
50
51 }
52
53 }

线程不安全-问题代码

9.2
Interlocked类
Interlock类用于使变量的简单语句原子化,线程安全方式递增、递减、交换和读取。i++不是线程安全的(包含3个操作:从内存获取、递增1、存储回内存,这些操作都可以被线程调度器打断)。

9.3 Monitor类
lock语句由编译器解释为Monitor类: Moniter.Enter(obj) ;  
Monitor.Exit(obj);
Monitor类的一个优点:可以添加一个等待被锁定的超市值。Monitor.TryEnter(lockObj,500,ref
lockToken);


 1             public void DoTheJob()
2 {
3 for (int i = 0; i < 50000; i++)
4 {
5 bool isLocked = false;
6 goLabel:
7 Monitor.TryEnter(sharedState, 500, ref isLocked);
8 if (isLocked)
9 {
10 sharedState.State += 1;
11 Monitor.Exit(sharedState);
12 }
13 else
14 {
15 Console.WriteLine("lock failed.");
16 goto goLabel;
17 }
18
19 }
20 }

Monitor.TryEnter

9.4
SpinLock结构
适合于有大量的锁定,而且锁定的时间非常短。用法非常接近于Monitor类。获得锁使用Enter()或者TryEnter(),释放锁使用Exit()方法。小心SpinLock的传送,因为是结构,所以会复制。

9.5 WaitHandle基类
Delegate BeginInvoke()
用waithandle.WaitOne(50,false)来bolck当前线程,
WaitHandle是一个抽象基类,用于等待一个信号量的设置。可以等待不同的信号,因为WaitHandle是一个基类,可以派生一些类。


        private static void Main(string[] args)
{
Action ac = () =>
{
Console.WriteLine("Action Begin.");
Thread.Sleep(2000);
Console.WriteLine("Action End.");

};

AsyncCallback callback = (o) =>
{
var cb = (Action)o.AsyncState;
cb.EndInvoke(o);
Console.WriteLine("Callback finished.");

};

IAsyncResult ar = ac.BeginInvoke(callback, ac);
while (true)
{
Console.Write(".");
if (ar.AsyncWaitHandle.WaitOne(50, true))
{
Console.WriteLine("Can get the result now.");
break;
}
}

Console.ReadLine();

}

AsyncWaitHandle

WaitOne() 等待一个,waitAll()等待多个对象,WaitAny等待多个对象的一个。WaitAll和WaitAny是静态方法。

WaitHandle基类有一个SafeWaitHandle属性,其中可以将本机句柄赋予一个操作系统资源,并等待该句柄。
Mutex、EventWaitHandle
和 Semaphore类继承自WaitHandle基类。所以可以等到使用它们。

9.6 Mutex类
Mutex(mutual
exclusion,互斥)是.net
Framework中提供多个集成同步访问的一个类。它非常类似于Monitor,只有一个线程能拥有锁定。只有一个线程能获得互斥锁定,访问受互斥访问的同步代码区域。
 
 
在Mutex类的构造函数中,可以指定互斥是否最初由主调线程拥有。定义互斥的名称,获得互斥是否存在的信息。
系统能识别有名称的Mutex


        private static void Main(string[] args)
{
bool isNew;
using (Mutex mutex = new Mutex(false, "ProMutext", out isNew))
{
if (isNew)
{
Console.WriteLine("Get mutex lock.");

}
else
{
Console.WriteLine("can‘t get mutex lock.");
}
Thread.Sleep(3000);
}
Thread.Sleep(1000000);
Console.ReadLine();

}

Mutex

9.7
Semaphore类
信号量非常类似于互斥,其区别是多个线程使用。信号量是一种技术的互斥锁定。使用信号量可以定义同时访问旗语锁定保护的资源的线程个数。
Semaphore类:可以命名,使用系统范围内的资源,允许不同进程间同步。


        static void Main()
{
int threadCount = 6;
int semaphoreCount = 4;
var semaphore = new Semaphore( semaphoreCount, semaphoreCount,"ProSemaphore");
var threads = new Thread[threadCount];

for (int i = 0; i < threadCount; i++)
{
threads[i] = new Thread(ThreadMain);
threads[i].Start(semaphore);
}

for (int i = 0; i < threadCount; i++)
{
threads[i].Join();
}
Console.WriteLine("All threads finished");

}

static void ThreadMain(object o)
{
Semaphore semaphore = o as Semaphore;
Trace.Assert(semaphore != null, "o must be a Semaphore type");
bool isCompleted = false;
while (!isCompleted)
{
if (semaphore.WaitOne(600))
{
try
{
Console.WriteLine("Thread {0} locks the semaphore",
Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(4000);
}
finally
{
semaphore.Release();
Console.WriteLine("Thread {0} releases the semaphore",
Thread.CurrentThread.ManagedThreadId);
isCompleted = true;
}
}
else
{
Console.WriteLine("Timeout for thread {0}; wait again",
Thread.CurrentThread.ManagedThreadId);
}
}
}

Semaphore(多线程&跨进程同步)

SemaphoreSlim类是对于较短等待时间进行了优化的轻型版本,不能跨进程。不能命名,不使用内核信号量,不能跨进程。


        private static void Main(string[] args)
{
int threadCount = 6;
int semaphoreCount = 4;
var semaphore = new SemaphoreSlim(semaphoreCount, semaphoreCount);
Thread[] threads = new Thread[threadCount];

for (int i = 0; i < threadCount; i++)
{
threads[i] = new Thread(ThreadMain);
threads[i].Start(semaphore);
}

for (int i = 0; i < threadCount; i++)
{
threads[i].Join();
}
Console.WriteLine("AllThread finished!");

Console.ReadLine();
}

static void ThreadMain(object o)
{
SemaphoreSlim semaphore = o as SemaphoreSlim;
Trace.Assert(semaphore != null, "o must be a Semphore type.");
bool isCompleted = false;
while (!isCompleted)
{
if (semaphore.Wait(100))
{
try
{
Console.WriteLine("thread {0} locks the semaphore", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(3000);
}
finally
{
semaphore.Release();
Console.WriteLine("Thread {0} release the semaphore", Thread.CurrentThread.ManagedThreadId);
isCompleted = true;
}
}
else
{
Console.WriteLine("Timeout for thread {0}; wait again ", Thread.CurrentThread.ManagedThreadId);
}
}
}

SemaphoreSlim

9.8 Event类
事件是另一个系统范围内的资源同步方法。为了从托管代码中使用系统事件,.net
framework提供了ManualResetEvent、AutoResetEvent、ManualResetEventSlim和CountdownEvent类。


       private static void Main(string[] args)
{
const int taskCount = 10;
var mEvents = new ManualResetEventSlim[taskCount];
var waitHandles = new WaitHandle[taskCount];
var calcs = new Calculator[taskCount];
TaskFactory taskFactory = new TaskFactory();
for (int i = 0; i < taskCount; i++)
{
mEvents[i] = new ManualResetEventSlim(false);
waitHandles[i] = mEvents[i].WaitHandle;
calcs[i] = new Calculator(mEvents[i]);

taskFactory.StartNew(calcs[i].Calculation, Tuple.Create(i + 1, i + 3));

}

for (int i = 0; i < taskCount; i++)
{
int index = WaitHandle.WaitAny(waitHandles);
if (index == WaitHandle.WaitTimeout)
{
Console.WriteLine("Timeout!!");

}
else
{
mEvents[index].Reset();
Console.WriteLine("finished task for {0}, result: {1}", index, calcs[index].Result);
Thread.Sleep(100);
}
}

Console.ReadLine();
}

public class Calculator
{
private ManualResetEventSlim mEvent;
public int Result { get; private set; }

public Calculator(ManualResetEventSlim ev)
{
this.mEvent = ev;
}

public void Calculation(Object obj)
{
Tuple<int, int> data = (Tuple<int, int>)obj;
Console.WriteLine("Task {0} starts calculation", Task.CurrentId);
Thread.Sleep((3000));
Result = data.Item1 + data.Item2;
Console.WriteLine("Task {0} is ready", Task.CurrentId);
mEvent.Set();
}
}

ManualResetEvent

把任务分支到多个任务中,并在以后合并结果,使用新的CountdownEvent类很有用。
不需要位每个任务创建一个单独的事件对象,而只需要创建一个事件对象。

var mEvents = new ManualResetEventSlim[taskCount];
// var
cEvent = new CountdownEvent(taskCount);

var waitHandles = new WaitHandle[taskCount];
var
calcs = new Calculator[taskCount];

int index = WaitHandle.WaitAny(waitHandles);//wait

//tasks
mEvent.Set();//all thread set;
//continue


        private static void Main(string[] args)
{
const int taskCount = 10;
var cEvent = new CountdownEvent(taskCount);

var calcs = new Calculator[taskCount];
TaskFactory taskFactory = new TaskFactory();
for (int i = 0; i < taskCount; i++)
{
calcs[i] = new Calculator(cEvent);

taskFactory.StartNew(calcs[i].Calculation, Tuple.Create(i + 1, i + 3));

}

cEvent.Wait();
Console.WriteLine("All finished.");

Console.ReadLine();
}

public class Calculator
{
private CountdownEvent cEvent;
public int Result { get; private set; }

public Calculator(CountdownEvent ev)
{
this.cEvent = ev;
}

public void Calculation(Object obj)
{
Tuple<int, int> data = (Tuple<int, int>)obj;
Console.WriteLine("Task {0} starts calculation", Task.CurrentId);
Thread.Sleep((3000));
Result = data.Item1 + data.Item2;
Console.WriteLine("Task {0} is ready", Task.CurrentId);
cEvent.Signal();
}
}

CountdownEvent

9.9 Barrier 类
适合于工作有多个任务分支且以后又需要合并工作的情况。

var barrier = new Barrier(numberTasks +
1);
 barrier.SignalAndWait();//wait
//tasks
barrier.RemoveParticipant();//2
left

barrier.RemoveParticipant();//1 left

//continue.

9.10
ReadWriterLockSlim类
允许多个读取器。同时只有一个写入器工作,此时读取器不能工作。


        private static List<int> items = new List<int>() { 0, 1, 2, 3, 4, 5 };
static ReaderWriterLockSlim rwl = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);

static void ReadMethod(object reader)
{
try
{
rwl.EnterReadLock();
for (int i = 0; i < items.Count; i++)
{
Console.WriteLine("read {0}, loop: {1}, item:{2}", reader, i, items[i]);
Thread.Sleep(40);
}
}
finally
{
rwl.ExitReadLock();
}
}

static void WriterMethod(object writer)
{
try
{
while (!rwl.TryEnterWriteLock(50))
{
Console.WriteLine("Writer {0} waiting ,current reader count: {1}", writer, rwl.CurrentReadCount);
}
Console.WriteLine("Writer{0} acquired the lock.", writer);
for (int i = 0; i < items.Count; i++)
{
items[i]++;
Thread.Sleep(50);

}
Console.WriteLine("Writer {0} finished.", writer);

}
finally
{
rwl.ExitWriteLock();
}
}
private static void Main(string[] args)
{
var taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None);
var tasks = new Task[6];
tasks[0] = taskFactory.StartNew(WriterMethod, 1);
tasks[1] = taskFactory.StartNew(ReadMethod, 1);
tasks[2] = taskFactory.StartNew(ReadMethod, 2);
tasks[3] = taskFactory.StartNew(WriterMethod, 2);
tasks[4] = taskFactory.StartNew(ReadMethod, 3);
tasks[5] = taskFactory.StartNew(ReadMethod, 4);
foreach (Task task in tasks)
{
task.Wait();

}

Console.WriteLine("All finished.");

Console.ReadLine();
}

ReadWriterLockSlim

10 Timer类

C# 线程、任务和同步

时间: 2024-08-29 15:13:39

C# 线程、任务和同步的相关文章

线程:Exchanger同步工具

可以在对中对元素进行配对和交换的线程的同步点,类似于交易,A拿着钱到达指定地点,B拿着物品到达指定地点,相互交换,然后各自忙各自的事去了. 1 package ch03; 2 3 import java.util.concurrent.Exchanger; 4 5 public class ExchangerTest { 6 7 public static void main(String[] args) { 8 final Exchanger<String> changer = new Ex

线程:CountDownLatch同步工具

一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 类似计数器,当计数器的值为0时,继续往下执行. 1 package ch03; 2 3 import java.util.Random; 4 import java.util.concurrent.CountDownLatch; 5 import java.util.concurrent.ExecutorService; 6 import java.util.concurrent.Executors; 7 8

线程互斥与同步

能解决下面的问题,基本上就能理解线程互斥与同步了. 子线程循环10次,主线程循环100次,接着子线程循环10,主线程循环100次.如此往复循环50次. 1 package cn.lah.thread; 2 3 public class TraditionalThreadCommunication { 4 5 public static void main(String[] args) { 6 7 final Business business = new Business(); 8 new Th

C# 线程之间的同步

1.通过Join方法,暂停当前线程 Thread secondThread = new Thread(new ThreadStart(ThreadMethod)); secondThread.Start(); ... secondThread.Join(); 2.通过启动APM异步操作的方法,得到一个IAsyncResult对象,通过它有三种方法使得两个线程同步. public interface IAsynResult { object AsyncState{get; } WaitHandle

线程--promise furture 同步

http://www.cnblogs.com/haippy/p/3279565.html std::promise 类介绍 promise 对象可以保存某一类型 T 的值,该值可被 future 对象读取(可能在另外一个线程中),因此 promise 也提供了一种线程同步的手段.在 promise 对象构造时可以和一个共享状态(通常是std::future)相关联,并可以在相关联的共享状态(std::future)上保存一个类型为 T 的值. 可以通过 get_future 来获取与该 prom

线程:CyclicBarrier同步工具类

一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点.比如公司组织活动出去玩,需要在公司门口一起搭车去.每个人从家里出发去公司门口,到达的时间肯定先后不一样,所以公司的车要一直等待,等所有人到齐后,才开车出发.CyclicBarrier就类似这样的功能,当所有线程到达"屏蔽点"的时候,才往下走. 具体等待多少根线程到达,可以在构造方法里指定CyclicBarrier(int parties). 当你的parties设为3的时候,假设只有2根线程到达此处,那程序会一直在此等待.

vc++高级班之多线程篇[7]---线程间的同步机制②

//示例代码: CStringArray g_ArrString; UINT __cdecl ThreadProc(LPVOID lpParameter) { int startIdx = (int)lpParameter; for (int idx = startIdx; idx < startIdx+100; ++idx) { CString str; str.Format(_T("%d"), idx); g_ArrString.Add(str); } return 0; }

线程的资源同步问题

卖出的票为负数的情况: class MyThread22 implements Runnable {     private int ticket = 10;     public void run() {         for (int i = 0; i < 100; i++) {             if (ticket > 0) {                 try {                    Thread.sleep(1000);               

vc++高级班之多线程篇[6]---线程间的同步机制①

①.线程同步的必要性: int g_Num = 0; UINT __cdecl ThreadProc(LPVOID lpParameter) { for (int idx = 0; idx < 100; ++idx) { g_Num = g_Num+1; CString strNum; strNum.Format(_T("%d"), g_Num); g_Num = g_Num-1; } return 0; } void CThreadTestDlg::OnBnClickedBtn

进程 线程 多线程 并发 同步异步

进程 线程 多线程 并发 同步异步 很多人对进程,线程,多线程,并发,同步,异步等概念感到困惑,这都是大学没好好听课的缘故啊.咱在这里帮感到概念给感到困惑的同学复习下. 程序 程序用来描述计算机所完成的独立功能,并在时间上严格地按前后次序相继地进行计算机操作序列集合,是一个静态概念. 进程 并发执行的程序在执行过程中分配和管理资源的基本单位.是一个动态的执行过程. 进程的静态描述 进程控制块PCB 有关程序段 该程序员对齐进行操作的数据结构集 进程控制块PCB 进程控制块PCB是系统管制进程存在