.NET的PLC帮助类

2023/11/29 10:27:22

 TCP和UDP协议:

        TCP(传输控制协议)和UDP(用户数据报协议)是TCP/IP协议簇中的两种核心协议。它们在传输层上提供数据传输服务,但具有不同的特性和功能。

        TCP协议是一种提供可靠、面向连接的字节流服务的传输协议。在数据传输前,发送方和接收方必须先建立TCP连接,然后才能进行数据传输。它通过超时重发、丢弃重复数据、数据检验等功能,确保数据能从一端传输到另一端。

        UDP协议则是一种简单的面向数据报的传输层协议,它提供的是非面向连接、不可靠的数据流传输服务。由于UDP在传输数据报前不需要在客户和服务器之间建立连接,也没有超时重发等机制,因此其传输速度相对较快。但这也意味着它不能提供数据传输的可靠性保障。

        总的来说,TCP和UDP各有其优点和使用场景。TCP主要应用于可靠性要求高的应用,如网页浏览、文件传输等;而UDP则更适合于可靠性要求低、对传输速度和经济性有一定需求的应用,如视频流、游戏等。

RS-232和RS-475通信接口标准及Modbus协议:

        RS-232是一种常见的串行通信接口标准,由美国电子工业协会(EIA)联合贝尔系统公司、调制解调器厂家及计算机终端生产厂家于1970年共同制定。其全名为“数据终端设备(DTE)和数据通信设备(DCE)之间串行二进制数据交换接口技术标准”。它通常被应用于计算机、调制解调器和各种电子设备之间的通信连接。

        RS-475是一种由美国电子工业协会(EIA)制定的半双工通信接口标准,它通常被应用于电子设备之间的数据传输。它采用平衡驱动和差分接收,因此具有较好的抗干扰能力,同时传输距离较远,可以达到数百米甚至千米级别。与RS-232不同的是,RS-475通常采用9针D型连接器,并且其引脚定义也与RS-232有所不同。RS-475主要用于工业、科学和医疗等领域的设备间通信,但由于其半双工的限制,应用场景不如RS-232和RS-485广泛。

        Modbus是一种串行通信协议,最初由Modicon公司(现在的施耐德电气 Schneider Electric)于1979年开发,用于可编程逻辑控制器(PLC)之间的通信。此协议已经成为工业领域通信协议的业界标准,并且现在是工业电子设备之间常用的连接方式。西门子的S1200和S1500用的就是Modbus协议

        Modbus协议定义了一个控制器能够识别的消息结构,不管它们是经过何种网络进行通信的。它描述了控制器请求访问其他设备的过程,如果回应来自其他设备的请求,以及怎样侦测错误并记录。它制定了消息域格局和内容的公共格式。当在Modbus网络上通信时,此协议决定了每个控制器需要知道它们的设备地址,识别按地址发来的消息,决定要产生何种行动。如果需要回应,控制器将生成反馈信息并用Modbus协议发出。总的来说,Modbus是一种应用于电子控制器之间的通用语言,通过它,不同厂商生产的控制设备可以连成工业网络,进行集中监控。

一、使用HslCommunication程序集,官网:胡工科技。

using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using HslCommunication;
using HslCommunication.Profinet.Siemens;
using HslCommunication.Profinet.Omron;
using HslCommunication.Profinet.Keyence;

namespace PLC.Class
{
    public class PLCHelper
    {
        #region 连接西门子PLC--SiemensS7Net
        /// <summary>
        /// 连接西门子PLC--SiemensS7Net
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口</param>
        /// <returns></returns>
        private bool ConnectSiemens(SiemensS7Net siemens, string ip, int port)
        {
            try
            {
                IPAddress ipaddress;
                bool flag = !IPAddress.TryParse(ip, out ipaddress);
                if (flag)
                {
                    return false;
                }
                else
                {
                    siemens.IpAddress = ip;
                    siemens.Port = port;
                    OperateResult operateResult = siemens.ConnectServer();
                    bool isSuccess = operateResult.IsSuccess;
                    if (isSuccess)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// 给西门子PLC点位写信号
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口</param>
        /// <param name="point">PLC点位</param>
        /// <param name="flag">给点位传入的值</param>
        /// <returns></returns>
        public bool WriteFlagBySiemens(SiemensS7Net siemens, string ip, int port, string point, short flag)
        {
            if (ConnectSiemens(siemens, ip, port))
            {
                OperateResult result = siemens.Write(point, flag);
                siemens.ConnectClose();
                return result.IsSuccess;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 读取西门子PLC的状态
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口</param>
        /// <param name="point">PLC点位</param>
        /// <returns></returns>
        public bool ReadBoolBySiemens(SiemensS7Net siemens, string ip, int port, string point)
        {
            if (ConnectSiemens(siemens, ip, port))
            {
                OperateResult<bool> value = siemens.ReadBool(point);
                siemens.ConnectClose();
                return value.Content;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 读取西门子PLC的值
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口</param>
        /// <param name="point">PLC点位</param>
        /// <param name="length">读取长度</param>
        /// <returns></returns>
        public string ReadStringBySiemens(SiemensS7Net siemens, string ip, int port, string point, ushort length)
        {
            if (ConnectSiemens(siemens, ip, port))
            {
                OperateResult<string> result = new OperateResult<string>();
                result = siemens.ReadString(point, length);
                string source = string.Empty;

                if (!string.IsNullOrEmpty(result.Content))
                {
                    source = result.Content;
                }
                else
                {
                    for (int i = 0; i < 3; i++)
                    {
                        Thread.Sleep(10);
                        result = siemens.ReadString(point, length);
                        if (!string.IsNullOrEmpty(result.Content))
                        {
                            source = result.Content;
                            break;
                        }
                    }
                    if (string.IsNullOrEmpty(result.Content))
                    {
                        return "未读取到PLC信息";
                    }
                }
                siemens.ConnectClose();
                return source;
            }
            else
            {
                return "false";
            }
        }

        /// <summary>
        /// 清空西门子PLC点位中的值
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <param name="point"></param>
        /// <param name="length">写入的长度</param>
        /// <returns></returns>
        public bool ClearPlcPocketBySiemens(SiemensS7Net siemens, string ip, int port, string point, int length, string flag = " ")
        {
            if (ConnectSiemens(siemens, ip, port))
            {
                OperateResult result = siemens.Write(point, flag, length);
                siemens.ConnectClose();
                return result.IsSuccess;
            }
            else
            {
                return false;
            }
        }
        #endregion

        #region 连接欧姆龙PLC--OmronFinsNet
        /// <summary>
        /// 连接欧姆龙PLC--OmronFinsNet
        /// </summary>
        /// <param name="omron"></param>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <returns></returns>
        private bool ConnectOmron(OmronFinsNet omron, string ip, int port)
        {
            //OmronFinsUdp
            try
            {
                IPAddress ipaddress;
                bool flag = !IPAddress.TryParse(ip, out ipaddress);
                if (flag)
                {
                    return false;
                }
                else
                {
                    omron.IpAddress = ip;
                    omron.Port = port;
                    omron.SA1 = 239;
                    //if (ip240.Contains(ip))
                    //{
                    //    omron.SA1 = 240;
                    //}
                    //else
                    //{
                    //    omron.SA1 = 239;
                    //}
                    //omron.DA1 = 24;
                    OperateResult operateResult = omron.ConnectServer();
                    if (!operateResult.IsSuccess)
                    {
                        for (int i = 0;i < 3;i++)
                        {
                            operateResult = omron.ConnectServer();
                            if (operateResult.IsSuccess)
                            {
                                break;
                                //return true;
                            }
                        }
                        //SA1使用239连接不上,则采取240连接
                        if (!operateResult.IsSuccess)
                        {
                            omron.SA1 = 240;
                            for (int i = 0; i < 3; i++)
                            {
                                operateResult = omron.ConnectServer();
                                if (operateResult.IsSuccess)
                                {
                                    break;
                                    //return true;
                                }
                            }
                        }
                        //if (!isSuccess)
                        //{
                        //    return false;
                        //}
                    }
                    return operateResult.IsSuccess;
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog(ex.ToString());
                return false;
            }
        }

        /// <summary>
        /// 给欧姆龙PLC点位写信号
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口</param>
        /// <param name="point">PLC点位</param>
        /// <param name="flag">给点位传入的值</param>
        /// <returns></returns>
        public bool WriteShortByOmron(OmronFinsNet omron, string ip, int port, string point, short flag)
        {
            //if (ConnectOmron(omron, ip, port))
            //{
            OperateResult result = omron.Write(point, flag);
            if (!result.IsSuccess)
            {
                for (int i = 0;i < 3;i++)
                {
                    result = omron.Write(point,flag);
                    if (result.IsSuccess)
                    {
                        break;
                        //return true;
                    }
                }
                //if (!result.IsSuccess)
                //{
                //    return false;
                //}
            }
            //omron.ConnectClose();
            return result.IsSuccess;
            //}
            //else
            //{
            //    return false;
            //}
        }

        //写入float值
        public bool WriteFloatByOmron(OmronFinsNet omron, string ip, int port, string point, float flag)
        {
            //if (ConnectOmron(omron, ip, port))
            //{
            OperateResult result = omron.Write(point, flag);
            if (!result.IsSuccess)
            {
                for (int i = 0; i < 3; i++)
                {
                    result = omron.Write(point, flag);
                    if (result.IsSuccess)
                    {
                        break;
                        //return true;
                    }
                }
                //if (!result.IsSuccess)
                //{
                //    return false;
                //}
            }
            //omron.ConnectClose();
            return result.IsSuccess;
            //}
            //else
            //{
            //    return false;
            //}
        }

        public string WritePointByOmron(OmronFinsNet omron, string ip, int port, List<string> pointlst, List<string> dataTypelst, List<string> valuelst,string type,List<string> filedlst)
        {
            //int sucNum = 0;
            string errorFileds = "";
            try
            {
                if (type == "EDIT")
                {
                    //return 0;
                    return "";
                }
                //调用时以下6个点位不写入
                List<string> addNotWritePoint = new List<string>() { "D200", "D202", "D210", "D212", "D0", "D469" };
                if (ConnectOmron(omron, ip, port))
                {
                    for (int i = 0; i < pointlst.Count; i++)
                    {
                        if (addNotWritePoint.Contains(pointlst[i]))
                        {
                            continue;
                        }

                        if (dataTypelst[i] == "FLOAT" && !string.IsNullOrEmpty(valuelst[i]))
                        {
                            float flag = Convert.ToSingle(valuelst[i]);
                            bool result = WriteFloatByOmron(omron, ip, port, pointlst[i], flag);
                            if (result)
                            {
                                //sucNum++;
                            }
                            else
                            {
                                if (errorFileds.Length > 0)
                                {
                                    errorFileds += ",";
                                }
                                errorFileds += filedlst[i];
                                LogHelper.WriteErrLog($"IP:{ip},端口:{port},点位:{pointlst[i]},值:{valuelst[i]}写入失败!");
                            }
                        }
                        else if (dataTypelst[i] == "SHORT" && !string.IsNullOrEmpty(valuelst[i]))
                        {
                            short flag = Convert.ToInt16(valuelst[i]);
                            bool result = WriteShortByOmron(omron, ip, port, pointlst[i], flag);
                            if (result)
                            {
                                //sucNum++;
                            }
                            else
                            {
                                if (errorFileds.Length > 0)
                                {
                                    errorFileds += ",";
                                }
                                errorFileds += filedlst[i];
                                LogHelper.WriteErrLog($"IP:{ip},端口:{port},点位:{pointlst[i]},值:{valuelst[i]}写入失败!");
                            }
                        }
                    }
                    //return sucNum;
                }
                //else
                //{
                //    return sucNum;
                //}
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog(ex.ToString());
            }
            finally
            {
                omron.ConnectClose();
            }
            //return sucNum;
            return errorFileds;
        }

        /// <summary>
        /// 读取欧姆龙PLC的状态
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口</param>
        /// <param name="point">PLC点位</param>
        /// <returns></returns>
        public bool ReadBoolByOmron1(OmronFinsNet omron, string ip, int port, string point)
        {
            if (ConnectOmron(omron, ip, port))
            {
                OperateResult<bool> value = omron.ReadBool(point);
                omron.ConnectClose();
                return value.Content;
            }
            else
            {
                return false;
            }
        }

        //读取float型数据
        public float ReadFloatByOmron(OmronFinsNet omron, string ip, int port, string point)
        {
            //if (ConnectOmron(omron, ip, port))
            //{
            OperateResult<float> value = omron.ReadFloat(point);
            if (!value.IsSuccess)
            {
                for (int i = 0;i < 3;i++)
                {
                    value = omron.ReadFloat(point);
                    if (value.IsSuccess)
                    {
                        break;
                        //return value.Content;
                    }
                }
                //if (!value.IsSuccess)
                //{
                //    return 0;
                //}
            }
            //omron.ConnectClose();
            if (value.IsSuccess)
            {
                return value.Content;
            }
            else
            {
                return 0;
            }
            //}
            //else
            //{
            //    return 0;
            //}
        }

        //读取short型数据
        public short ReadShortByOmron(OmronFinsNet omron, string ip, int port, string point)
        {
            //if (ConnectOmron(omron, ip, port))
            //{
            OperateResult<short> value = omron.ReadInt16(point);
            if (!value.IsSuccess)
            {
                for (int i = 0; i < 3; i++)
                {
                    value = omron.ReadInt16(point);
                    if (value.IsSuccess)
                    {
                        break;
                        //return value.Content;
                    }
                }
                //if (!value.IsSuccess)
                //{
                //    return 0;
                //}
            }
            //omron.ConnectClose();
            if (value.IsSuccess)
            {
                return value.Content;
            }
            else
            {
                return 0;
            }
            //}
            //else
            //{
            //    return 0;
            //}
        }

        //读取Bool类型数据
        public bool ReadBoolByOmron(OmronFinsNet omron, string ip, int port, string point)
        {
            OperateResult<bool> value = omron.ReadBool(point);
            if (!value.IsSuccess)
            {
                for (int i = 0; i < 3; i++)
                {
                    value = omron.ReadBool(point);
                    if (value.IsSuccess)
                    {
                        break;
                    }
                }
            }
            if (value.IsSuccess)
            {
                return value.Content;
            }
            else
            {
                return false;
            }
        }

        public string ReadPointByOmron(OmronFinsNet omron, string ip, int port, List<string> filedlst, List<string> pointlst, List<string> datatypelst)
        {
            string result = "0";
            JObject jObj = new JObject();

            try
            {
                if (ConnectOmron(omron, ip, port))
                {
                    for (int i = 0; i < pointlst.Count; i++)
                    {
                        if (datatypelst[i] == "FLOAT")
                        {
                            result = ReadFloatByOmron(omron, ip, port, pointlst[i]).ToString();
                        }
                        else if (datatypelst[i] == "SHORT")
                        {
                            result = ReadShortByOmron(omron, ip, port, pointlst[i]).ToString();
                        }
                        else if (datatypelst[i] == "BOOL" && pointlst[i] == "H10")
                        {
                            //涂布单双面3个点位细分—00:单面,01:双面,01;02:连续
                            bool res = false;
                            List<string> H10s = new List<string>() { "H10.00", "H10.01", "H10.02" };
                            foreach (string h10 in H10s)
                            {
                                res = ReadBoolByOmron(omron, ip, port, h10);
                                if (res)
                                {
                                    result = h10.Substring(h10.Length - 1,1);
                                    break;
                                }
                            }
                        }

                        jObj.Add(new JProperty(filedlst[i], result));
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog(ex.ToString());
            }
            finally
            {
                omron.ConnectClose();
            }
            
            return jObj.ToString();
        }

        /// <summary>
        /// 读取欧姆龙PLC的值
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口</param>
        /// <param name="point">PLC点位</param>
        /// <param name="length">读取长度</param>
        /// <returns></returns>
        public string ReadStringByOmron(OmronFinsNet omron, string ip, int port, string point, ushort length)
        {
            if (ConnectOmron(omron, ip, port))
            {
                OperateResult<string> result = new OperateResult<string>();
                result = omron.ReadString(point, length);
                string source = string.Empty;

                if (!string.IsNullOrEmpty(result.Content))
                {
                    source = result.Content;
                }
                else
                {
                    for (int i = 0; i < 3; i++)
                    {
                        Thread.Sleep(10);
                        result = omron.ReadString(point, length);
                        if (!string.IsNullOrEmpty(result.Content))
                        {
                            source = result.Content;
                            break;
                        }
                    }
                    if (string.IsNullOrEmpty(result.Content))
                    {
                        return "未读取到PLC信息";
                    }
                }
                omron.ConnectClose();
                return source;
            }
            else
            {
                return "false";
            }
        }

        /// <summary>
        /// 清空欧姆龙PLC点位中的值
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <param name="point"></param>
        /// <param name="length">写入的长度</param>
        /// <returns></returns>
        public bool ClearPlcPocketByOmron(OmronFinsNet omron, string ip, int port, string point, int length, string flag = " ")
        {
            if (ConnectOmron(omron, ip, port))
            {
                OperateResult result = omron.Write(point, flag, length);
                omron.ConnectClose();
                return result.IsSuccess;
            }
            else
            {
                return false;
            }
        }
        #endregion

        #region  连接基恩士PLC--KeyenceMcNet
        /// <summary>
        /// 连接基恩士PLC--KeyenceMcNet
        /// </summary>
        /// <param name="omron"></param>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <returns></returns>
        private bool ConnectKeyence(KeyenceMcNet keyence, string ip, int port)
        {
            try
            {
                IPAddress ipaddress;
                bool flag = !IPAddress.TryParse(ip, out ipaddress);
                if (flag)
                {
                    return false;
                }
                else
                {
                    keyence.IpAddress = ip;
                    keyence.Port = port;
                    OperateResult operateResult = keyence.ConnectServer();
                    bool isSuccess = operateResult.IsSuccess;
                    if (isSuccess)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// 给基恩士PLC点位写信号
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口</param>
        /// <param name="point">PLC点位</param>
        /// <param name="flag">给点位传入的值</param>
        /// <returns></returns>
        public bool WriteFlagByKeyence(KeyenceMcNet keyence, string ip, int port, string point, short flag)
        {
            if (ConnectKeyence(keyence, ip, port))
            {
                OperateResult result = keyence.Write(point, flag);
                keyence.ConnectClose();
                return result.IsSuccess;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 读取基恩士PLC的状态
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口</param>
        /// <param name="point">PLC点位</param>
        /// <returns></returns>
        public bool ReadBoolByKeyence(KeyenceMcNet keyence, string ip, int port, string point)
        {
            if (ConnectKeyence(keyence, ip, port))
            {
                OperateResult<bool> value = keyence.ReadBool(point);
                keyence.ConnectClose();
                return value.Content;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 读取基恩士PLC的值
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口</param>
        /// <param name="point">PLC点位</param>
        /// <param name="length">读取长度</param>
        /// <returns></returns>
        public string ReadStringByKeyence(KeyenceMcNet keyence, string ip, int port, string point, ushort length)
        {
            if (ConnectKeyence(keyence, ip, port))
            {
                OperateResult<string> result = new OperateResult<string>();
                result = keyence.ReadString(point, length);
                string source = string.Empty;

                if (!string.IsNullOrEmpty(result.Content))
                {
                    source = result.Content;
                }
                else
                {
                    for (int i = 0; i < 3; i++)
                    {
                        Thread.Sleep(10);
                        result = keyence.ReadString(point, length);
                        if (!string.IsNullOrEmpty(result.Content))
                        {
                            source = result.Content;
                            break;
                        }
                    }
                    if (string.IsNullOrEmpty(result.Content))
                    {
                        return "未读取到PLC信息";
                    }
                }
                keyence.ConnectClose();
                return source;
            }
            else
            {
                return "false";
            }
        }

        /// <summary>
        /// 清空基恩士PLC点位中的值
        /// </summary>
        /// <param name="siemens"></param>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <param name="point"></param>
        /// <param name="length">写入的长度</param>
        /// <returns></returns>
        public bool ClearPlcPocketByKeyence(KeyenceMcNet keyence, string ip, int port, string point, int length, string flag = " ")
        {
            if (ConnectKeyence(keyence, ip, port))
            {
                OperateResult result = keyence.Write(point, flag, length);
                keyence.ConnectClose();
                return result.IsSuccess;
            }
            else
            {
                return false;
            }
        }
        #endregion
    }
}


http://www.jnnr.cn/a/982733.html

相关文章

docker安装apisix全教程包含windows和linux

docker安装apisix 一、Windows安装1、首先需要安装docker和docker compose&#xff0c;如果直接安装docker desktop&#xff0c;会自动安装docker compose。2、重新启动电脑3、访问 Docker 的下载&#xff08;[https://www.docker.com/products/docker-desktop](https://www.do…

kafka各版本消息介绍

kafka各版本消息介绍 V0 offset&#xff1a;分区中的偏移量message size&#xff1a;消息大小crc32(4B):crc32校验值。校验范围为magic至value之间。magic(1B):消息格式版本号&#xff0c;此版本的magic值为0。attributes (1B):消息的属性。总共占1个字节&#xff0c;低3 位表…

tp6 + swagger 配置文档接口

ThinkPHP 6.0 运行环境要求PHP7.2&#xff0c;兼容PHP8.1 安装 composer create-project topthink/think tp 6.0.*如果需要更新框架使用 composer update topthink/framework文档 完全开发手册 swagger 文档 注解文档 安装包 composer require zircote/swagger-php 引用…

BUUCTF reverse wp 21 - 30

[ACTF新生赛2020]rome 无壳, 直接拖进IDA32 y键把v2改成char[49], n键重命名为iuput int func() {int result; // eaxint v1[4]; // [esp14h] [ebp-44h]char input[49]; // [esp24h] [ebp-34h] BYREFstrcpy(&input[23], "Qsw3sj_lz4_Ujwl");printf("Please…

Python入门教程48:Pycharm永久镜像源的pip配置方法

国内几个好用的Python镜像服务器地址&#xff1a; 清华大学镜像站&#xff1a;https://pypi.tuna.tsinghua.edu.cn/simple/阿里云镜像站&#xff1a;https://mirrors.aliyun.com/pypi/simple/中科大镜像站&#xff1a;https://pypi.mirrors.ustc.edu.cn/simple/中国科技大学镜…

深入理解 Swift 新并发模型中 Actor 的重入(Reentrancy)问题

问题现象 我们知道,Swift 5.5 引入的新并发模型极大简化了并行逻辑代码的开发,更重要的是:使用新并发模型中的 Actor 原语可以大大降低并发数据竞争的可能性。 不过,即便 Actor 有如此神奇之功效,它也不是“万能药”,仍不能防止误用带来的问题。比如:Actor 重入(Reen…

Azure Arc 概要:功能、管理和应用场景详解,AZ900 考点示例

文章目录 本文大纲一、什么是 Azure Arc二、使用 Azure Arc 可以做什么操作三、使用 Azure Arc 可以管理什么资源3.1 如何使用Azure Arc与服务器? 四、Azure Arc 支持的主要场景五、在 AZ900 中的考点示例5.1 示例题 15.2 示例题 2 本文大纲 本文思维导图概述的主要内容&…

嵌入式Linux应用开发-面向对象-分层-分离及总线驱动模型

嵌入式Linux应用开发-面向对象-分层-分离及总线驱动模型 第八章 驱动设计的思想&#xff1a;面向对象/分层/分离8.1 面向对象8.2 分层8.3 分离8.4 写示例代码8.5 课后作业 第九章 驱动进化之路&#xff1a;总线设备驱动模型9.1 驱动编写的 3种方法9.1.1 传统写法9.1.2 总线设备…

DDS信号发生器波形发生器VHDL

名称&#xff1a;DDS信号发生器波形发生器 软件&#xff1a;Quartus 语言&#xff1a;VHDL 要求&#xff1a; 在EDA平台中使用VHDL语言为工具&#xff0c;设计一个常见信号发生电路&#xff0c;要求&#xff1a; 1. 能够产生锯齿波&#xff0c;方波&#xff0c;三角波&…

三、git的安装和配置

一、安装 1.官网下载&#xff1a;https://git-scm.com/download 下载最新版本&#xff0c;点击红框或篮筐处即可 2.点击下载好的安装包安装这个软件 3.一直点击next&#xff0c;直到出现install&#xff0c;点击install&#xff0c;安装完成后点击finish&#xff1a; 下载完成…

电脑技巧:推荐一款桌面增强工具AquaSnap

目录 一、软件介绍 二、功能介绍 2.1 窗口边缘停靠 2.2、 窗口平铺 2.3、 窗口对齐 2.4 窗口自动拉伸 2.5、同时移动多个窗口 2.6 、支持窗口置顶 2.7、 鼠标快捷方式 2.8、 键盘快捷键 三、软件特色 四、软件获取 一、软件介绍 AquaSnap(界面增强软件)是一款功能…

【学习笔记】CF1817F Entangled Substrings(基本子串结构)

前置知识&#xff1a;基本子串结构&#xff0c;SAM的结构和应用 学长博客 字符串理论比较抽象&#xff0c;建议直观的去理解它 子串 t t t的扩展串定义为 ext(t) : t ′ \text{ext(t)}:t ext(t):t′&#xff0c;满足 t t t是 t ′ t t′的子串&#xff0c;且 occ(t) occ(t…

C/C++进程线程超详细详解

目录 前言 一、进程基础 1.进程概念 2.进程特征 3.进程状态&#xff08;如图清晰可见&#xff09; 4&#xff0c;进程的标识 实例代码如下&#xff1a; 5.进程的种类 实例shell脚本程序如下: 二、进程API 1.创建子进程 实例代码如下&#xff1a; 2.exec函数族 函数…

《Upload-Labs》01. Pass 1~13

Upload-Labs 索引前言Pass-01题解 Pass-02题解总结 Pass-03题解总结 Pass-04题解 Pass-05题解总结 Pass-06题解总结 Pass-07题解总结 Pass-08题解总结 Pass-09题解 Pass-10题解 Pass-11题解 Pass-12题解总结 Pass-13题解 靶场部署在 VMware - Win7。 靶场地址&#xff1a;https…

Sentinel学习——sentinel的使用,引入依赖和配置 对消费者进行流控 对生产者进行熔断降级

前言 Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。 本篇博客介绍sentinel的使用&#x…

UE4/5数字人MetaHuman通过已有动画进行修改

目录 通过已有动画修改动画 开始制作 创建一个关卡序列 将动画序列烘焙到控制绑定 打开我们自己创建的动画序列 之后便是烘焙出来 通过已有动画修改动画 首先架设我们已经有相关的MetaHuman的动画&#xff0c;但是这个动画因为是外部导入进来的&#xff0c;所以可能会出…

opencv实现目标跟踪及视频转存

创建跟踪器 def createTypeTracker(trackerType): 读取视频第一帧&#xff0c;选择跟踪的目标 读第一帧。 ok, frame video.read() 选择边界框 bbox cv2.selectROI(frame, False) 初始化跟踪器 tracker_type ‘MIL’ tracker createTypeTracker(tracker_type) 用第一…

图像直方图的基础知识

直方图的概念 图像直方图反映了图像中的灰度分布规律。它描述每个灰度级具有的像元个数&#xff0c;但不包含这些像元在图像中的位置信息。任何一幅特定的图像都有唯一的直方图与之对应&#xff0c;但不同的图像可以有相同的直方图。如果一幅图像有两个不相连的区域组成&#…

【知识点】JavaScript中require的一些理解

以下内容源自个人理解&#xff0c;若有错误欢迎指出。 猜想 多个文件中require同一个文件时&#xff0c;对于首次出现的require&#xff0c;会去读取文件并执行一遍&#xff0c;然后加入缓存&#xff1b;之后当再次require到这个文件时&#xff0c;只会指向这个缓存&#xff0c…

ElasticSearch - 在 微服务项目 中基于 RabbitMQ 实现 ES 和 MySQL 数据异步同步(考点)

目录 一、数据同步 1.1、什么是数据同步 1.2、解决数据同步面临的问题 1.3、解决办法 1.3.1、同步调用 1.3.2、异步通知&#xff08;推荐&#xff09; 1.3.3、监听 binlog 1.3、基于 RabbitMQ 实现数据同步 1.3.1、需求 1.3.2、在“酒店搜索服务”中 声明 exchange、…
最新文章