C#多线程及同步示例简析

C#多线程及同步示例简析

在C#中,多线程编程可以提高CPU利用率,提高程序的响应速度,增强程序的稳定性。但多线程编程中也会遇到诸多问题,比如线程安全、死锁、优先级等问题,需要进行同步和协同操作。本文将从多线程编程和同步操作两个方面进行简要分析,并提供两个实例来加深读者的理解。

多线程编程示例

示例一:简单的启动线程和等待线程结束

using System;
using System.Threading;

class Program
{
    static void Main(string[] args)
    {
        Thread thread = new Thread(Worker);
        thread.Start();
        Console.WriteLine("主线程开始等待工作线程结束");
        thread.Join();
        Console.WriteLine("工作线程已结束");
    }

    static void Worker()
    {
        Console.WriteLine("工作线程正在工作...");
        Thread.Sleep(5000); // 模拟一些工作
        Console.WriteLine("工作线程已结束");
    }
}

上述示例中,通过创建Worker方法的线程,来模拟一些耗时的工作,而主线程则在启动此线程之后,等待线程结束,再继续执行代码。

示例二:线程安全的计数器

using System;
using System.Threading;

class Program
{
    static volatile int count = 0; // volatile确保写操作的可见性

    static void Main(string[] args)
    {
        Thread[] threads = new Thread[10];
        for (int i = 0; i < threads.Length; i++)
        {
            threads[i] = new Thread(Worker);
            threads[i].Start();
        }
        foreach (Thread thread in threads) thread.Join(); // 等待所有线程结束
        Console.WriteLine("计数器结果: " + count);
    }

    static void Worker()
    {
        for (int i = 0; i < 100000; i++) Interlocked.Increment(ref count); // 加锁保证访问安全
    }
}

上述示例中,创建10个线程,每个线程都会执行100000次的计数操作。由于多个线程可能会同时对计数器进行修改,会导致数据不一致或者程序崩溃等问题。因此,在每次修改计数器时,需要使用加锁保证访问的安全性。同时使用volatile关键字,确保写操作的可见性。

同步示例

示例一:互斥锁

using System;
using System.Threading;

class Program
{
    static bool stop = false;
    static Mutex mutex = new Mutex();

    static void Main(string[] args)
    {
        Thread thread1 = new Thread(Worker1);
        Thread thread2 = new Thread(Worker2);
        thread1.Start();
        thread2.Start();
        Console.ReadKey();
        stop = true;
    }

    static void Worker1()
    {
        while (!stop)
        {
            mutex.WaitOne();
            Console.WriteLine("Worker1正在工作...");
            Thread.Sleep(100);
            mutex.ReleaseMutex();
        }
        Console.WriteLine("Worker1已停止");
    }

    static void Worker2()
    {
        while (!stop)
        {
            mutex.WaitOne();
            Console.WriteLine("Worker2正在工作...");
            Thread.Sleep(200);
            mutex.ReleaseMutex();
        }
        Console.WriteLine("Worker2已停止");
    }
}

上述示例中,使用Mutex类来创建一个互斥锁,确保同一时刻只有一个线程能够访问共享资源。Worker1和Worker2线程会多次等待互斥锁,并分别对共享资源进行访问。

示例二:信号量

using System;
using System.Threading;

class Program
{
    static Semaphore sem = new Semaphore(2, 2); // 初始信号量为2,最大信号量为2

    static void Main(string[] args)
    {
        for (int i = 1; i <= 5; i++)
        {
            Thread thread = new Thread(Worker);
            thread.Name = "Worker" + i;
            thread.Start();
        }
        Console.ReadKey();
    }

    static void Worker()
    {
        Console.WriteLine(Thread.CurrentThread.Name + "等待信号量");
        sem.WaitOne(); //等待信号量
        Console.WriteLine(Thread.CurrentThread.Name + "开始工作");
        Thread.Sleep(2000);
        Console.WriteLine(Thread.CurrentThread.Name + "结束工作");
        sem.Release(); // 释放信号量
    }
}

上述示例中,使用Semaphore类来表示一个具有初始信号量的信号灯。多个Worker线程会在开始之前等待信号灯,只有在获得信号之后才能开始工作。在工作结束之后会释放信号灯。

总结

本文介绍了C#多线程编程和同步操作的相关知识,并提供了两个示例来帮助读者更好地理解。在实际应用中,多线程和同步操作需要结合具体业务场景进行设计和调整,以达到最优的效果。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#多线程及同步示例简析 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 你的账号密码是怎样丢失的?暴力破解攻击的检测和防御

    如何丢失账号密码? 网络钓鱼攻击:骗取用户输入个人账号和密码的方式,一些危险的钓鱼网站或邮件链接,会诱骗用户点击,并以形式稍有差别的假冒网站的形式出现在用户的视线内,让用户输入自己的账号密码,以达到骗取用户隐私信息的目的。 机器码攻击:黑客通过对该网站的渗透攻击,获得了服务器上的一些用户的信息,这些信息里包含了用户的账号、密码、电子邮件地址等,然后将这些用户…

    other 2023年6月27日
    00
  • 谷歌Nexus 5手机中的开发者选项在哪怎么开启

    下面是谷歌Nexus 5手机如何开启开发者选项的完整攻略: 1. 进入设置页面 首先,在您的Nexus 5手机上,滑动下拉通知栏,然后点击右上角的齿轮形状的“设置”图标,进入手机的设置页面。 2. 找到“关于手机”选项 在设置页面中,向下滑动页面找到 “设备” 标题,然后点击“关于手机”选项。 3. 连续点击“版本号” 在“关于手机”页面中,找到“版本号”一…

    other 2023年6月26日
    00
  • iOS7如何关闭后台应用程序使用教程

    以下是详细讲解“iOS7如何关闭后台应用程序使用教程”的完整攻略。 1. 什么是后台应用程序? 后台应用程序是指在你按下Home键回到桌面时仍在工作的应用程序,相当于你让它暂时挂起,但并没有完全退出。 2. 如何关闭后台应用程序? 在iOS7中关闭后台应用程序的方法如下: 2.1 双击Home键 双击Home键,屏幕下方会出现已打开的应用程序列表,然后用手指…

    other 2023年6月25日
    00
  • Shell全局变量、局部变量与特殊变量的具体使用

    Shell全局变量、局部变量与特殊变量的具体使用 在Shell中,变量的使用非常重要,特别是各种变量的使用方式。本篇文章将详细讲解Shell中的全局变量、局部变量与特殊变量,并给出一些示例说明。 全局变量 全局变量在整个程序运行时都是可用的,可以被所有函数或命令使用。在Shell中,定义全局变量不需要显示声明,直接赋值即可。例如: #!/bin/bash g…

    other 2023年6月27日
    00
  • word菜单栏开发工具和加载项怎么自定义?

    自定义Word菜单栏开发工具和加载项可以帮助用户快速访问自定义的宏和功能,提高工作效率。下面是关于如何自定义word菜单栏开发工具和加载项的攻略: 一、添加开发工具选项卡 打开Word,依次点击文件 – 选项 – 自定义功能区,在“主选项卡”下拉列表中选择“开发工具”,点击确定。此时开发工具选项卡会出现在Word的菜单栏上。 点击开发工具选项卡,可以看到其中…

    other 2023年6月25日
    00
  • 面试时必问的JVM运行时数据区详解

    面试时必问的JVM运行时数据区详解 在面试中,JVM(Java虚拟机)是一个常见的话题。了解JVM的运行时数据区是理解Java程序执行的关键。下面是对JVM运行时数据区的详细解释,包括两个示例说明。 1. 程序计数器(Program Counter Register) 程序计数器是JVM中的一块较小的内存区域。它的作用是指示当前线程执行的字节码指令的地址。在…

    other 2023年8月2日
    00
  • linux cgroups详细介绍

    Linux cgroups详细介绍 什么是cgroups cgroups(control groups)是Linux内核提供的一种机制,它允许你限制、分配和监控系统资源(如CPU、内存、磁盘IO等)的使用。cgroups可以通过文件系统的形式,将一组进程放置在一个子系统中。 cgroups的应用场景 cgroups常用于以下场景: 系统性能优化:通过控制资源…

    other 2023年6月27日
    00
  • 手机重启和关机再开机区别是什么 手机卡顿时关机好还是重启好

    手机重启和关机再开机区别是什么? 手机重启是什么? 当我们遇到手机出现问题,比如应用闪退、卡顿、操作失灵等情况时,我们通常会先尝试重启手机。重启手机的操作是关闭手机后再重新启动手机,类似于我们在电脑上的重启操作。在重新启动时,手机会重新加载系统,这既可以帮助清除掉一些系统内部的缓存,还能重新分配电力资源等,使手机得以快速运行。 手机关机再开机是什么? 手机关…

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部