ylbtech-LanguageSamples-Threading(线程处理)

ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-Threading(线程处理)
1.A,示例(Sample) 返回顶部

“线程处理”示例

本示例演示了下面的线程处理技术。有关更多信息,请参见线程处理(C# 编程指南) 。

  • 创建、启动和终止线程
  • 使用线程池
  • 线程同步和互交
安全说明

提供此代码示例是为了阐释一个概念,它并不代表最安全的编码实践,因此不应在应用程序或网站中使用此代码示例。对于因将此代码示例用于其他用途而出现的偶然或必然的损害,Microsoft 不承担任何责任。

在 Visual Studio 中生成并运行“线程处理”示例

  1. 在“解决方案资源管理器”中,右击“ThreadStartStop”项目并单击“设为启动项目”。
  2. 在“调试”菜单上,单击“开始执行(不调试)”。
  3. 对于 ThreadPool 和 ThreadSync,分别重复上述步骤。

从命令行生成并运行“线程”示例

  1. 使用“更改目录”命令转到“Threads”目录。
  2. 键入以下命令:
    cd ThreadStartStop
    csc ThreadStartStop.cs
    ThreadStartStop
  3. 键入以下命令:
    cd ..\ThreadPool
    csc ThreadPool.cs
    ThreadPool
  4. 键入以下命令:
    cd ..\ThreadSync
    csc ThreadSync.cs
    ThreadSync
1.B,ThreadStartStop 示例代码(Sample Code)返回顶部

1.B.1, ThreadStartStop.cs

// 版权所有(C) Microsoft Corporation。保留所有权利。
// 此代码的发布遵从
// Microsoft 公共许可(MS-PL,http://opensource.org/licenses/ms-pl.html)的条款。
//
//版权所有(C) Microsoft Corporation。保留所有权利。

using System;
using System.Threading;

public class Worker
{
    // 启动线程时调用此方法。
    public void DoWork()
    {
        while (!_shouldStop)
        {
            Console.WriteLine("worker thread: working...");
        }
        Console.WriteLine("worker thread: terminating gracefully.");
    }
    public void RequestStop()
    {
        _shouldStop = true;
    }
    // Volatile 用于向编译器提示此数据
    // 成员将由多个线程访问。
    private volatile bool _shouldStop;
}

public class WorkerThreadExample
{
    static void Main()
    {
        // 创建线程对象。这不会启动该线程。
        Worker workerObject = new Worker();
        Thread workerThread = new Thread(workerObject.DoWork);

        // 启动辅助线程。
        workerThread.Start();
        Console.WriteLine("main thread: Starting worker thread...");

        // 循环直至辅助线程激活。
        while (!workerThread.IsAlive);

        // 为主线程设置 1 毫秒的休眠,
        // 以使辅助线程完成某项工作。
        Thread.Sleep(1);

        // 请求辅助线程自行停止:
        workerObject.RequestStop();

        // 使用 Join 方法阻塞当前线程,
        // 直至对象的线程终止。
        workerThread.Join();
        Console.WriteLine("main thread: Worker thread has terminated.");
    }
}

1.B.2,

1.B.EXE,

main thread: Starting worker thread...
worker thread: working...
worker thread: working...
worker thread: working...
worker thread: working...
worker thread: working...
worker thread: working...
worker thread: working...
worker thread: working...
worker thread: terminating gracefully.
main thread: Worker thread has terminated.
请按任意键继续. . .

1.B

1.B,ThreadPool 示例代码2(Sample Code)返回顶部

1.B.1, ThreadPool.cs

// 版权所有(C) Microsoft Corporation。保留所有权利。
// 此代码的发布遵从
// Microsoft 公共许可(MS-PL,http://opensource.org/licenses/ms-pl.html)的条款。
//
//版权所有(C) Microsoft Corporation。保留所有权利。

using System;
using System.Threading;

// Fibonacci 类为使用辅助
// 线程执行长时间的 Fibonacci(N) 计算提供了一个接口。
// N 是为 Fibonacci 构造函数提供的,此外还提供了
// 操作完成时对象发出的事件信号。
// 然后,可以使用 FibOfN 属性来检索结果。
public class Fibonacci
{
    public Fibonacci(int n, ManualResetEvent doneEvent)
    {
        _n = n;
        _doneEvent = doneEvent;
    }

    // 供线程池使用的包装方法。
    public void ThreadPoolCallback(Object threadContext)
    {
        int threadIndex = (int)threadContext;
        Console.WriteLine("thread {0} started...", threadIndex);
        _fibOfN = Calculate(_n);
        Console.WriteLine("thread {0} result calculated...", threadIndex);
        _doneEvent.Set();
    }

    // 计算第 N 个斐波纳契数的递归方法。
    public int Calculate(int n)
    {
        if (n <= 1)
        {
            return n;
        }
        else
        {
            return Calculate(n - 1) + Calculate(n - 2);
        }
    }

    public int N { get { return _n; } }
    private int _n;

    public int FibOfN { get { return _fibOfN; } }
    private int _fibOfN;

    ManualResetEvent _doneEvent;
}

public class ThreadPoolExample
{
    static void Main()
    {
        const int FibonacciCalculations = 10;

        // 每个 Fibonacci 对象使用一个事件
        ManualResetEvent[] doneEvents = new ManualResetEvent[FibonacciCalculations];
        Fibonacci[] fibArray = new Fibonacci[FibonacciCalculations];
        Random r = new Random();

        // 使用 ThreadPool 配置和启动线程:
        Console.WriteLine("launching {0} tasks...", FibonacciCalculations);
        for (int i = 0; i < FibonacciCalculations; i++)
        {
            doneEvents[i] = new ManualResetEvent(false);
            Fibonacci f = new Fibonacci(r.Next(20,40), doneEvents[i]);
            fibArray[i] = f;
            ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i);
        }

        // 等待池中的所有线程执行计算...
        WaitHandle.WaitAll(doneEvents);
        Console.WriteLine("Calculations complete.");

        // 显示结果...
        for (int i= 0; i<FibonacciCalculations; i++)
        {
            Fibonacci f = fibArray[i];
            Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN);
        }
    }
}

1.B.2,

1.B.EXE,

launching 10 tasks...
thread 0 started...
thread 1 started...
thread 1 result calculated...
thread 2 started...
thread 2 result calculated...
thread 3 started...
thread 0 result calculated...
thread 4 started...
thread 4 result calculated...
thread 5 started...
thread 5 result calculated...
thread 6 started...
thread 6 result calculated...
thread 7 started...
thread 7 result calculated...
thread 8 started...
thread 8 result calculated...
thread 9 started...
thread 3 result calculated...
thread 9 result calculated...
Calculations complete.
Fibonacci(27) = 196418
Fibonacci(23) = 28657
Fibonacci(21) = 10946
Fibonacci(38) = 39088169
Fibonacci(25) = 75025
Fibonacci(25) = 75025
Fibonacci(37) = 24157817
Fibonacci(27) = 196418
Fibonacci(29) = 514229
Fibonacci(37) = 24157817
请按任意键继续. . .

1.B,

1.B,ThreadSync 示例代码3(Sample Code)返回顶部

1.B.1, ThreadSync.cs

// 版权所有(C) Microsoft Corporation。保留所有权利。
// 此代码的发布遵从
// Microsoft 公共许可(MS-PL,http://opensource.org/licenses/ms-pl.html)的条款。
//
//版权所有(C) Microsoft Corporation。保留所有权利。

using System;
using System.Threading;
using System.Collections;
using System.Collections.Generic;

// 将线程同步事件封装在此类中,
// 以便于将这些事件传递给 Consumer 和
// Producer 类。
public class SyncEvents
{
    public SyncEvents()
    {
        // AutoResetEvent 用于“新项”事件,因为
        // 我们希望每当使用者线程响应此事件时,
        // 此事件就会自动重置。
        _newItemEvent = new AutoResetEvent(false);

        // ManualResetEvent 用于“退出”事件,因为
        // 我们希望发出此事件的信号时有多个线程响应。
        // 如果使用 AutoResetEvent,事件
        // 对象将在单个线程作出响应之后恢复为
        // 未发信号的状态,而其他线程将
        // 无法终止。
        _exitThreadEvent = new ManualResetEvent(false);

        // 这两个事件也放在一个 WaitHandle 数组中,以便
        // 使用者线程可以使用 WaitAny 方法
        // 阻塞这两个事件。
        _eventArray = new WaitHandle[2];
        _eventArray[0] = _newItemEvent;
        _eventArray[1] = _exitThreadEvent;
    }

    // 公共属性允许对事件进行安全访问。
    public EventWaitHandle ExitThreadEvent
    {
        get { return _exitThreadEvent; }
    }
    public EventWaitHandle NewItemEvent
    {
        get { return _newItemEvent; }
    }
    public WaitHandle[] EventArray
    {
        get { return _eventArray; }
    }

    private EventWaitHandle _newItemEvent;
    private EventWaitHandle _exitThreadEvent;
    private WaitHandle[] _eventArray;
}

// Producer 类(使用一个辅助线程)
// 将项异步添加到队列中,共添加 20 个项。
public class Producer
{
    public Producer(Queue<int> q, SyncEvents e)
    {
        _queue = q;
        _syncEvents = e;
    }
    public void ThreadRun()
    {
        int count = 0;
        Random r = new Random();
        while (!_syncEvents.ExitThreadEvent.WaitOne(0, false))
        {
            lock (((ICollection)_queue).SyncRoot)
            {
                while (_queue.Count < 20)
                {
                    _queue.Enqueue(r.Next(0, 100));
                    _syncEvents.NewItemEvent.Set();
                    count++;
                }
            }
        }
        Console.WriteLine("Producer thread: produced {0} items", count);
    }
    private Queue<int> _queue;
    private SyncEvents _syncEvents;
}

// Consumer 类通过自己的辅助线程使用队列
// 中的项。Producer 类使用 NewItemEvent
// 将新项通知 Consumer 类。
public class Consumer
{
    public Consumer(Queue<int> q, SyncEvents e)
    {
        _queue = q;
        _syncEvents = e;
    }
    public void ThreadRun()
    {
        int count = 0;
        while (WaitHandle.WaitAny(_syncEvents.EventArray) != 1)
        {
            lock (((ICollection)_queue).SyncRoot)
            {
                int item = _queue.Dequeue();
            }
            count++;
        }
        Console.WriteLine("Consumer Thread: consumed {0} items", count);
    }
    private Queue<int> _queue;
    private SyncEvents _syncEvents;
}

public class ThreadSyncSample
{
    private static void ShowQueueContents(Queue<int> q)
    {
        // 对集合进行枚举本来就不是线程安全的,
        // 因此在整个枚举过程中锁定集合以防止
        // 使用者和制造者线程修改内容
        // 是绝对必要的。(此方法仅由
        // 主线程调用。)
        lock (((ICollection)q).SyncRoot)
        {
            foreach (int i in q)
            {
                Console.Write("{0} ", i);
            }
        }
        Console.WriteLine();
    }

    static void Main()
    {
        // 配置结构,该结构包含线程同步
        // 所需的事件信息。
        SyncEvents syncEvents = new SyncEvents();

        // 泛型队列集合用于存储要制造和使用的
        // 项。此例中使用的是“int”。
        Queue<int> queue = new Queue<int>();

        // 创建对象,一个用于制造项,一个用于
        // 使用项。将队列和线程同步事件传递给
        // 这两个对象。
        Console.WriteLine("Configuring worker threads...");
        Producer producer = new Producer(queue, syncEvents);
        Consumer consumer = new Consumer(queue, syncEvents);

        // 为制造者对象和使用者对象创建线程
        // 对象。此步骤并不创建或启动
        // 实际线程。
        Thread producerThread = new Thread(producer.ThreadRun);
        Thread consumerThread = new Thread(consumer.ThreadRun);

        // 创建和启动两个线程。
        Console.WriteLine("Launching producer and consumer threads...");
        producerThread.Start();
        consumerThread.Start();

        // 为制造者线程和使用者线程设置 10 秒的运行时间。
        // 使用主线程(执行此方法的线程)
        // 每隔 2.5 秒显示一次队列内容。
        for (int i = 0; i < 4; i++)
        {
            Thread.Sleep(2500);
            ShowQueueContents(queue);
        }

        // 向使用者线程和制造者线程发出终止信号。
        // 这两个线程都会响应,由于 ExitThreadEvent 是
        // 手动重置的事件,因此除非显式重置,否则将保持“设置”。
        Console.WriteLine("Signaling threads to terminate...");
        syncEvents.ExitThreadEvent.Set();

        // 使用 Join 阻塞主线程,首先阻塞到制造者线程
        // 终止,然后阻塞到使用者线程终止。
        Console.WriteLine("main thread waiting for threads to finish...");
        producerThread.Join();
        consumerThread.Join();
    }
}

1.B.2,

1.B.EXE,

Configuring worker threads...
Launching producer and consumer threads...
87 65 95 1 77 97 21 64 77 43 50 63 4 99 84 29 5 26 35
41 15 71 91 26 56 21 21 18 51 15 9 25 50 5 65 82 76 99
99 23 41 24 6 80 37 95 87 52 83 96 86 67 34 47 10 42 44 17
40 10 44 38 75 35 85 85 92 33 25 33 86 48 12 99 7 92 36 17
Signaling threads to terminate...
main thread waiting for threads to finish...
Producer thread: produced 2015587 items
Consumer Thread: consumed 2015568 items
请按任意键继续. . .

1.B,

1.C,下载地址(Free Download)返回顶部
作者:ylbtech
出处:http://ylbtech.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
时间: 2024-10-12 22:42:41

ylbtech-LanguageSamples-Threading(线程处理)的相关文章

python模块介绍-threading: 线程 管理并发操作

定义线程 最简单的方法:使用target指定线程要执行的目标函数,再使用start()启动. 语法: class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}) group恒为None,保留未来使用.target为要执行的函数名.name为线程名,默认为Thread-N,通常使用默认即可.但服务器端程序线程功能不同时,建议命名. #!/usr/bin/env python3 # coding=utf

pythonl练习笔记——threading线程中的事件Event

1 事件Event 使用方法:e = threading.Event() Event对象主要用于线程间通信,确切地说是用于主线程控制其他线程的执行. Event事件提供了三个方法:wait等待.clear清除信号False.set设置信号True. Event事件实现通信机制:全局定义了一个"Flag"(默认为False),若Flag信号被clear为False,则执行event.wait方法时会阻塞:若Flag信号被set为True,则执行event.wait方法时便不阻塞. Eve

多进程 multiprocessing 多线程Threading 线程池和进程池concurrent.futures

multiprocessing.procsess 定义一个函数 def func():pass 在if __name__=="__main__":中实例化 p = process(target=子进程要执行的函数,args(函数的参数且必须以元组的方式传参)) p.start() 开启子进程 p.join() 感知子进程的结束,主进程等待子进程执行完后才退出 p.terminate() 结束一个子进程 p.is_alive() 查看某个进程是否还在运行 属性 p.name p.pid

Python Threading 线程/互斥锁/死锁/GIL锁

导入线程包 import threading 准备函数线程,传参数 t1 = threading.Thread(target=func,args=(args,)) 类继承线程,创建线程对象 class MyThread(threading.Thread) def run(self): pass if __name__ == "__main__": t = MyThread() t.start() 线程共享全面变量,但在共享全局变量时会出现数据错误问题使用 threading 模块中的

进程 线程 threading模块

# 进程:本质上就是一个程序在一个数据集上的一次动态执行过程(抽象的概念) # 进程一般由程序.数据集(程序运行过程中所需要使用的资源).进程控制块(记录进程的外部特征,描述进程的执行变化过程)三部分组成 # 进程是最小的资源单位 # 线程的出现是为了降低上下文切换的消耗,提高系统的并发性,并突破一个进程只能干一样事的缺陷,使到进程内并发成为可能# 线程:是最小的执行单位 # 进程与线程的联系与区别 # 1.一个程序至少有一个进程,一个进程至少有一个线程 (进程可以理解成线程的容器) # 2.进

Python线程的用法 函数式线程_thread和threading 样例

函数式线程写起来比较简单,但是功能没有threading那么高级,先来个函数式编程样例: #!/usr/bin/python #coding: utf-8 #————————————————————————函数式线程———————————————————————————————————————— #QQ496631085 小和 XiaoHe import _thread import time def print_time(threadName,delay): count = 0 while c

Python并发编程-进程 线程 协程

一.进程 进程:就是一个程序在一个数据集上的一次动态执行过程. 进程由三部分组成: 1.程序:我们编写的程序用来描述进程要完成哪些功能以及如何完成 2.数据集:数据集则是程序在执行过程中所需要使用的资源 3.进程控制块:进程控制块用来记录进程的外部特征,描述进程的执行变化过程,系统可以利用它来控制和管理进程,它是系统感 知进程存在的唯一标志. 二.线程                                                                        

.NET 进程和线程

一.进程:需要有用Process类用法一:Process.Start("calc");该方法弊端:有许多程序不知道它的运行名字到底是什么,如果写错了,就会出现程序崩溃错误用法二://实例化进程类Process p = new Process();//创建进程开启路径对象ProcessStartInfo psi = new ProcessStartInfo(textBox1.Text);//进程类开启路径指向p.StartInfo = psi;//启动进程,不是立刻开启,什么时候开启时由

线程进程

进程:Process.Start("calc");//括号内是计算机可识别的应用程序名 弊端:有许多程序不知道它的运行名字到底是什么,如果写错了,就会出现程序崩溃错误(防止崩溃可以try住) //实例化进程类Process p = new Process();//创建进程开启路径对象ProcessStartInfo psi = new ProcessStartInfo(textBox1.Text);//进程类开启路径指向p.StartInfo = psi;//启动进程,不是立刻开启,什

c#中如何跨线程调用windows窗体控件?

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; //线程操作引用的命名空间 namespace windowform线程操作 { p