开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 1426|回复: 9
收起左侧

[C#图文教程] 易转C# - 6 - 基本多线程

[复制链接]
结帖率:95% (84/88)
发表于 2023-7-15 00:24:51 | 显示全部楼层 |阅读模式   美国
备注都在源码里拉,写了好几天的,比网上那些大长串好多了。

[C#] 纯文本查看 复制代码
using System;
using System.Threading;

using System.Diagnostics;
using System.Runtime.InteropServices;


namespace ThreadExample
{
    class Program
    {

        static void Main(string[] args)
        {
            ZombieThreadExample();
            while (true)
            {
                Thread.Sleep(2000);
            }
        }
        //=============
        public static void ThreadPoolExample()
        {
            int Number, completionPortThreads;
            ThreadPool.GetMaxThreads(out Number, out completionPortThreads);
            ThreadPool.SetMaxThreads(100, completionPortThreads); //第二个参数一般不需要改变,ChatGPT解释是:
                                                                  //第二个参数completionPortThreads指定了完成端口线程的数量。
                                                                  //完成端口线程用于处理异步I/O操作的完成事件。
                                                                  //当一个I/O操作完成时,由完成端口线程池中的线程来调用相关的回调方法。
            ThreadPool.GetMinThreads(out Number, out completionPortThreads);
            ThreadPool.SetMinThreads(50, completionPortThreads);


            for (int i = 0; i < 500; i++)
            {
                ThreadPool.QueueUserWorkItem(ThreadPoolThread, i);

                //new WaitCallback(ThreadPoolThread) //也可以
            }

            Console.ReadLine();
        }
        public static void ThreadPoolThread(object state)
        {
            Console.WriteLine("Task {0} is running on a thread from the thread pool.", state);
            Thread.Sleep(1000);
            Console.WriteLine("Task {0} exited.", state);
        }

        //=============
        public static void SpinLockExample()
        {
            // 互斥 、自旋、非重入、只能用于极短暂的运算。
            //会一直占用CPU
            //New Bing答案:
            SpinLock _spinLock = new SpinLock();
            bool lockTaken = false;
            try
            {
                _spinLock.Enter(ref lockTaken);
                // Do some work here.
            }
            finally
            {
                if (lockTaken) _spinLock.Exit();
            }
        }
        //=============
        public static volatile testClass testc = new testClass();
        public static volatile int a = 0;
        public static void Interlocked_volatileExample()
        {

            // volatile ≠ 数据不丢失
            //由于中断只能在当前指令完成后提供服务,因此即使内存未对齐,数据也永远不会损坏。

            // https://stackoverflow.com/questi ... eyword-be-used-in-c

            //经过测试:class
            //volatile - 49871
            //no volatile - 49843


            // a
            //原子锁 ----- volatile ------ 值1 ------- 值2
            // √   -----  √    -----    50000 -----  50000
            // √   -----  ×    -----    50000 -----  50000
            // ×   -----  √    -----    49646 -----  49715
            // ×   -----  ×    -----    49764 -----  49350
            // volatile 关键字只能应用于 class 或 struct 的字段。 不能将局部变量声明为 volatile。
            // 因为它们不在线程之间共享,但是a可以,编译器不报错


            Thread thread;

            for (int i = 0; i < 100; i++) // 100*500 = 50,000
            {
                thread = new Thread(() =>
                {

                    for (int i2 = 0; i2 < 500; i2++)
                    {
                        Interlocked.Increment(ref a);
                        testc.a++;
                        //Interlocked.Increment(ref testc.a);
                        Thread.Sleep(10);
                    }


                });
                thread.Start();
            }


            Thread.Sleep(10000);
            Console.WriteLine($"a:{a}");
            Console.WriteLine($"testc.a:{testc.a}");
        }
        //=============
        public static void JoinExample()
        {
            Stopwatch stopwatch = new Stopwatch();
            Thread thread = new Thread(() =>
            {
                Thread.Sleep(100000);
            });
            Thread thread1 = new Thread(() =>
            {
                Console.WriteLine("starting");
                thread.Join(2000); //等待线程1,超时2000秒
                Console.WriteLine("finished");

            });

            stopwatch.Start();


            thread.Start();
            thread1.Start();
            thread1.Join();


            stopwatch.Stop();
            Console.WriteLine(stopwatch.ElapsedMilliseconds); // Thread.Sleep(100000);
        }

        //=============
        public static Mutex mutex = new Mutex(false, "Global\\MyApp_TestApp_gfh5e3rsfdiuhvw9rttbfwhb43 "); //加上Global关键字无视切换user
        //禁止程序重复运行
        //互斥体
        public static void mutexExample()
        {
            Console.WriteLine(Process.GetCurrentProcess().MainModule.FileName);

            if (!mutex.WaitOne(1000))
            {
                mutex.Dispose();
                Console.WriteLine("Can not enter!");
                Console.ReadLine();
                Environment.Exit(1);
            }

            //mutex.ReleaseMutex();


            AppDomain.CurrentDomain.ProcessExit += (object sender, EventArgs e) =>
            {
                //Process.Start("calc.exe");
                //Process.Start(Process.GetCurrentProcess().MainModule.FileName); //作死行为
                mutex.Dispose();

            };

            while (true)
            {
                Console.WriteLine("enter...");
                Thread.Sleep(2000);
            }
        }

        //=============
        public static void AutoResetEvent() //单个释放线程
        {
            AutoResetEvent autoResetEvent = new AutoResetEvent(false);

            Thread thread;
            Random random = new Random();
            Console.WriteLine("creating");
            for (int i = 0; i < 5; i++)
            {
                thread = new Thread(() =>
                {
                    autoResetEvent.WaitOne();
                    Console.WriteLine("Start to working");
                    //autoResetEvent.Reset(); //不需要
                    Thread.Sleep(1000);
                    Console.WriteLine($"exit");
                    autoResetEvent.Set();


                });
                thread.Start();
            }
            Console.WriteLine("created");
            autoResetEvent.Set();
        }
        public static void AutoResetEvent_ResetExample()
        {
            AutoResetEvent autoResetEvent = new AutoResetEvent(false);

            Thread thread;


            Console.WriteLine("creating");
            thread = new Thread(() =>
            {
                autoResetEvent.WaitOne();
                Console.WriteLine("Start to working");
                Thread.Sleep(1000);
                Console.WriteLine($"exit");
            });

            autoResetEvent.Reset(); //如果被reset,会阻止执行WaitOne
            thread.Start();

            Thread.Sleep(4000);
            Console.WriteLine("set");
            autoResetEvent.Set();



        }
        //=============
        public static void ManualResetEvent() //会释放阻塞的所有线程
        {
            ManualResetEvent manualResetEvent = new ManualResetEvent(false);

            Thread thread;
            Random random = new Random();
            Console.WriteLine("creating");
            for (int i = 0; i < 5; i++)
            {
                thread = new Thread(() =>
                {
                    manualResetEvent.WaitOne();
                    Console.WriteLine("Start to working");
                    //manualResetEvent.Reset();
                    Thread.Sleep(1000);
                    Console.WriteLine($"exit");
                    //manualResetEvent.Set();


                });
                thread.Start();
            }
            Console.WriteLine("created");

            Thread.Sleep(2000);
            manualResetEvent.Set();

            manualResetEvent.Reset(); //reset之后会阻止waitone
            //如果没有reset,会继续执行waitone

            thread = new Thread(() =>
            {
                Console.WriteLine("last");
                manualResetEvent.WaitOne();
                Console.WriteLine("last Start to working");
                //manualResetEvent.Reset();
                Thread.Sleep(1000);
                Console.WriteLine($"exit");
                //manualResetEvent.Set();


            });

            thread.Start();


        }
        //=============
        public static void Semaphore() //信号量
        {
            Semaphore semaphore = new Semaphore(0, 5);
            Thread thread;
            Random random = new Random();
            Console.WriteLine("creating");
            for (int i = 0; i < 30; i++)
            {
                thread = new Thread(() =>
                {

                    semaphore.WaitOne();
                    Console.WriteLine("Star to sleep");
                    //Thread.Sleep(5000);
                    Thread.Sleep(random.Next(1000, 3001));
                    Console.WriteLine($"avalible number {semaphore.Release()}");


                });
                thread.Start();
            }
            Console.WriteLine("created");
            for (int i = 0; i < 5; i++)
            {
                semaphore.Release();
            }
        }
        //=============
        public static void MonitorExample()
        {
            //lock关键字是基于monitor的

            object monitor = new object();
            Thread thread;
            for (int i = 0; i < 50; i++)
            {
                thread = new Thread(() =>
                {
                    if (!Monitor.TryEnter(monitor))
                    {
                        Console.WriteLine($"can not enter, waiting:{Thread.CurrentThread.ManagedThreadId}");
                        Monitor.Enter(monitor);
                    } //坑》》》》》TryEnter - 如果能进入,就进入,如果不能进入,就返回假并继续向下执行
                    Console.WriteLine("locking...");
                    Thread.Sleep(20);
                    Console.WriteLine("exit");
                    Monitor.Exit(monitor);
                });
                thread.Start();
            }
        }
        //=============
        [DllImport("kernel32.dll")]
        private static extern void ExitThread(uint dwExitCode);
        public static void ZombieThreadExample()
        {
            // https://stackoverflow.com/questi ... ombies-exist-in-net
            using (var file = System.IO.File.Open("test.txt", System.IO.FileMode.OpenOrCreate))
            {
                ExitThread(0);
            }
        }
        //=============

    }

    class testClass
    {
        public int a = 0;
    }
}




ps:volatile class没搞明白,有谁懂吗,谢谢谢谢
结帖率:95% (84/88)

签到天数: 3 天

 楼主| 发表于 2023-8-2 01:34:52 | 显示全部楼层   泛播地址
补充一些小知识:
                        Interlocked.Increment(ref a); //加一
                        Interlocked.Add(ref a, -10);  //减10
                        Interlocked.Exchange(ref a, 99); //赋值

                        //例如,要原子地将一个整数变量的值设置为10,但仅当它当前的值为7时,可以这样写:
                        Interlocked.CompareExchange(ref a, 10, 7);
                        //Interlocked.CompareExchange(ref int location1, int value, int comparand)
回复 支持 反对

使用道具 举报

结帖率:100% (5/5)

签到天数: 8 天

发表于 2023-7-29 09:56:12 | 显示全部楼层   湖北省潜江市
陽陽陽 发表于 2023-7-28 00:14
大佬,我还没有学到

我也是刚学.都还不懂,委托啊,还有async/await也都很难搞懂
回复 支持 反对

使用道具 举报

结帖率:95% (84/88)

签到天数: 3 天

 楼主| 发表于 2023-7-28 00:14:55 | 显示全部楼层   美国

大佬,我还没有学到
回复 支持 反对

使用道具 举报

结帖率:100% (5/5)

签到天数: 8 天

发表于 2023-7-27 20:52:24 | 显示全部楼层   湖北省潜江市
Task好用些吧?
回复 支持 反对

使用道具 举报

结帖率:100% (14/14)

签到天数: 22 天

发表于 2023-7-15 10:25:31 | 显示全部楼层   湖北省咸宁市
c#应该也有输入api名字,自动声明的插件吧
回复 支持 反对

使用道具 举报

结帖率:95% (84/88)

签到天数: 3 天

 楼主| 发表于 2023-7-15 00:38:36 | 显示全部楼层   美国
E语言|菜鸟 发表于 2023-7-15 00:28
c#不好使啊。。写的一下给人拿走了


反汇编固然厉害,但当我全部开源,阁下又将如何应对

点评

拿来吧你   湖北省武汉市  发表于 2023-7-15 01:26
回复 支持 反对

使用道具 举报

结帖率:80% (16/20)

签到天数: 22 天

发表于 2023-7-15 00:28:11 | 显示全部楼层   广东省广州市
c#不好使啊。。写的一下给人拿走了
回复 支持 反对

使用道具 举报

结帖率:95% (84/88)

签到天数: 3 天

 楼主| 发表于 2023-7-15 00:26:43 | 显示全部楼层   美国
说真的,自己不敢相信这是自己写出来的
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表