首页 > 其他分享 >dotnet 测试 SemaphoreSlim 的 Wait 是否保持进入等待的顺序先进先出

dotnet 测试 SemaphoreSlim 的 Wait 是否保持进入等待的顺序先进先出

时间:2024-09-12 08:53:17浏览次数:8  
标签:origin git SemaphoreSlim var semaphore dotnet new 先进先出 Wait

本文记录我测试 dotnet 里面的 SemaphoreSlim 锁,在多线程进入 Wait 等待时,进行释放锁时,获取锁执行权限的顺序是否与进入 Wait 等待的顺序相同。测试的结果是 SemaphoreSlim 的 Wait 大部分情况是先进先出,按照 Wait 的顺序出来的,但是压力测试下也存在乱序,根据官方文档说明不应该依赖 SemaphoreSlim 的 Wait 做排队顺序

根据如下的官方文档说明,可以看到多线程进入时是没有保证顺序出来的:

If multiple threads are blocked, there is no guaranteed order, such as FIFO or LIFO, that controls when threads enter the semaphore.

尽管实际测试下,大部分情况都是完全按照顺序输出的,测试代码如下

var taskList = new List<Task>();
var locker = new object();

ThreadPool.SetMinThreads(100, 100);
ThreadPool.SetMaxThreads(100,100);
var semaphore = new SemaphoreSlim(0, 1);

var autoResetEvent = new AutoResetEvent(false);

for (int i = 0; i < 100; i++)
{
    var n = i;
    taskList.Add(Task.Run(() =>
    {
        autoResetEvent.Set();

        semaphore.Wait();

        lock (locker)
        {
            Console.WriteLine(n);
        }

        semaphore.Release();
    }));

    autoResetEvent.WaitOne();
}

semaphore.Release();

Task.WaitAll(taskList.ToArray());

运行之后大概能看到输出是顺序的

本文以上代码放在githubgitee 欢迎访问

可以通过如下方式获取本文的源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin a8a6fa2078b33e184c21e997956e665ddf52945b

以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin a8a6fa2078b33e184c21e997956e665ddf52945b

获取代码之后,进入 RijallcijiDuqewerbu 文件夹

由于我担心 Task 存在影响,同步也更改了 Thread 的版本,代码如下

var taskList = new List<Thread>();
var locker = new object();

var semaphore = new SemaphoreSlim(0, 1);

var autoResetEvent = new AutoResetEvent(false);

for (int i = 0; i < 100; i++)
{
    var n = i;

    var thread = new Thread(() =>
    {
        autoResetEvent.Set();

        semaphore.Wait();

        lock (locker)
        {
            Console.WriteLine(n);
        }

        semaphore.Release();
    });

    taskList.Add(thread);
    thread.Start();

    autoResetEvent.WaitOne();
}

semaphore.Release();

运行以上代码,依然大部分时候看到输出都是顺序的

尽管大部分输出都是顺序的,但是好开发者是不应该依赖 Wait 能够实现先进先出的效果的

更改的代码放在 githubgitee 欢迎访问

可以通过如下方式获取本文的源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 9273d7a649c656a95db608d9735be77e12d87600

以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 9273d7a649c656a95db608d9735be77e12d87600

获取代码之后,进入 RijallcijiDuqewerbu 文件夹

标签:origin,git,SemaphoreSlim,var,semaphore,dotnet,new,先进先出,Wait
From: https://www.cnblogs.com/lindexi/p/18000484

相关文章

  • dotnet 测试 Mutex 的 WaitOne 是否保持进入等待的顺序先进先出
    本文记录我测试dotnet里面的Mutex锁,在多线程进入WaitOne等待时,进行释放锁时,获取锁执行权限的顺序是否与进入WaitOne等待的顺序相同。测试的结果是Mutex的WaitOne是乱序的,不应该依赖Mutex的WaitOne做排队顺序以下是测试程序代码vartaskList=newList<Task>();......
  • Packaging.DebUOS 专门为 dotnet 应用制作 UOS 安装包
    Packaging.DebUOS是我所在的团队开发开源的一款专门用在为dotnet的应用制作成为符合要求的UOS统信系统软件安装包的工具,此工具可以辅助开发者使用现有的工具链经过简单的配置即可完成安装包的制作设计思想Packaging.DebUOS旨在通过使用csproj项目文件等方式进行配置,避免......
  • Dotnetty学习笔记——自定义初始化处理器
    常常我们需要开一个服务单,对接不同的客户端,编码器、解码器等都不同,需要针对不同IP添加不同的处理器。publicclassCustomInitializer:Channellnitializer<lSocketChannel>{Action<string,string>_dealMsgAction;lServer_server;publicCustomInitializer(Action<st......
  • # dotnet如何设置restore package path,依赖和项目放在一起
    dotnet如何设置restorepackagepath,依赖和项目放在一起配置说明再.csproj中添加如下配置,然后dotnetrestore,可以依赖包放到和项目一起,从而方便移动到没有网络的电脑上执行<RestorePackagesPath>../packages</RestorePackagesPath>所需的依赖包就会复制一份到本地,如下......
  • dotnet 默认创建的 JsonContent 没有 Content Length 的内容头
    本文记录一个dotnet的设计问题,默认创建出来的JsonContent对象的Headers里,是没有Content-Length信息的如下面代码创建一个JsonContent对象usingSystem.Net.Http.Json;varfoo=newFoo();varjsonContent=JsonContent.Create(foo);classFoo{publicin......
  • dotnet X11 多次调用 XPutImage 是否能做到渲染同步
    本文将告诉大家我在麒麟系统和统信系统以及分别搭配飞腾和兆芯处理器的设备上,使用连续的XPutImage方法推送界面,测试是否能够在一次渲染内完成。测试结论是不能做到渲染同步本文的核心测试代码如下XPutImage(display,handle,gc,refxImage,@event.ExposeEvent.x,@......
  • dotnet C# 结构体出方法弹栈之后的行为
    本文记录我在.NET9里测试的行为,在方法里面创建的在栈上的结构体,在方法执行结束之后,栈上的结构体将会被弹栈进入不受管理区域,此时的结构体内存内容不会立刻被清空或被改写这是我在对dotnetX11栈空间被回收导致调用XPutShmImage闪退博客的内容进行更多的测试,确保和X11没......
  • QTabWidget自定义样式(仿DotNetBar)
    QSS如下,若需要tab栏背景色需要添加ui->tabWidget->setAttribute(Qt::WA_StyledBackground);语句使background-color生效,这个时候qtdesigner中仍然看不到背景色,但是不要担心它是生效的,只需在属性中勾上autofillbackground即可在designer中预览(该属性在QWidget属性组中,实际上勾不勾......
  • 「队列」实现FIFO队列(先进先出队列|queue)的功能 / 手撕数据结构(C++)
    概述队列,是一种基本的数据结构,也是一种数据适配器。它在底层上以链表方法实现。队列的显著特点是他的添加元素与删除元素操作:先加入的元素总是被先弹出。一个队列应该应该是这样的:--------------QUEUE-------------———————————......
  • dotnet hello world
    参考资料dotnet命令参考使用dotnettest和xUnit在.NET中对C#进行单元测试DeclaringInternalsVisibleTointhecsprojXUnit输出消息创建控制台项目#创建项目目录mdDotnetStudycdDotnetStudy#创建解决方案dotnetnewsln#创建控制台项目,-n:名称,--use......