标签目录:摩登3平台靠谱吗

摩登3娱乐怎么样?_最新消息: 美商柏恩与德国Kaschke KG(GmbH and Co)正式向德国联邦政府-卡特尔办公室申请合并审查

德国.哥廷根, 2020年12月10日– 2020年11月24日Bourns 与德国Kaschke KG(GmbH and Co)向德国联邦政府卡特尔办公室正式提出公司合并申请事宜。德国Kaschke KG(GmbH and Co)为知名定制电感组件和铁氧体的市场领先设计商和制造商,其母公司Kaschke Components GmbH同样是欧洲知名半导体及电子组件制造商。 Bourns 表示提交该文件的目的是希望当地政府允许双方建立全球战略合作伙伴关系,以开发新的磁性产品,包括:电源变压器和扼流圈,替客户打造高效,稳健的电源器。 Bourns与Kaschke持续针对战略联盟的形式和条款进行讨论,一旦获得合并批准并满足一定的结案条件,该战略联盟即有望达成。 双方首选的战略合作伙伴关系形式是股权收购,这将使原与Kaschke交易的客户和供货商合同以及Kaschke全球员工的聘雇安排在此交易结束亦不受影响。 本次策略合作关系将Kaschke广泛的定制设计、特有铁氧体知识,结合Bourns专业应用的知识,来设计出独特的新产品,相信这结合会带来新的火花,也为工业和替代能源市场带来新的价值。 Kaschke总裁Silke Baumgartner 表示:「我很高兴能与Bourns建立联盟,Bourns的历史和核心价值观与Kaschke完全一致。我们相信Kaschke和Bourns的结合将使我们能够开发出完整的产品组合,帮助我们的客户满足汽车,工业和新能源市场中下一代电源所面临的充满挑战的EMI滤波要求。此外这些新产品将使客户可以通过简单的设计和成本优化来满足他们的设计目标。」 Bourns.总裁兼首席运营官Al Yost同时表示:「透过新材料和快速的切换速度来降低开关损耗使得半导体产业向前迈向一大步。我们很高兴与Kaschke合作开发新产品,现在正是需要新的磁性材料和产品来跟上趋势。以增强新一代电源能量转换。」

摩登3测速代理_图说 Linux 高性能网络架构的那些事

1. 落寞的小黑 入冬了,最近天气相当冷,周五晚上小林下班奔地铁站,收到了好基友小黑的微信: 于是 小林掉头扫了个单车奔五道口了,小黑靠谱地选了个不错的位置。 小黑: 你今天下班挺早呀! 小林: 就咱这觉悟,心里有工作,哪里都是办公桌,不要拘泥于形式嘛。 明显能感觉得到小黑哥最近好像比较累,之前眼里bulingbuling闪的光是看不到了。 小林: 下午去面的哪家?啥岗位?咋样? 小黑: 是一家做自动驾驶的创业公司,网站是看团队介绍还不错,就去看看了,这次没咋准备,很多问题其实都熟悉,但是回答的不到位。 小林: 哦,明白了,那就是当时理解的不到位,稀里糊涂过去了,现在忽然问起来,想不起重点。 小黑: 差不多吧,问我都做过哪些高性能的网络框架模型,也就是IO和事件驱动那一套。 话说完,小黑喝了一大口啤酒,小林看出了小黑心里有一些落寞。 毕竟在帝都这个地方竞争和工作压力,以及生活琐事都一直围绕着我们,但是金钱和好运都巧妙地避开了自己… 想到这里,小林也深深喝了一大口,我命由我不由天,开整! 小林:黑哥,你说这个问题确实不好回答,全是术语和略带歧义的东西,我觉得我们抓住本质去阐述就好。 小黑:来,请开始你的表演,我学习学习。 小林决定和小黑好好聊聊,Linux开发中常用的高性能网络框架中的一些事儿,火锅的映衬下让夜色和天气都不那么寒冷了。 通过本文你将会了解到以下内容: IO事件和IO复用 线程模型和事件驱动模型的架构 基于事件驱动的Reactor模式详解 同步IO和异步IO简介 2. IO事件和IO复用 2.1 什么是IO事件 IO指的是输入Input/输出Output,但是从汉语角度来说,出和入是相对的,所以我们需要个参照物。 这里我们的参照物选择为程序运行时的主存储空间,外部通常包括网卡、磁盘等。 有了上述的设定理解起来就方便多了,我们来一起看下: IO的本质是数据的流动,数据可以从网卡到程序内存,也可以从程序内存写到网卡,磁盘操作也是如此。 所以可以把常见的IO分为: 网络IO:内存和网卡的数据交互 文件IO:内存和磁盘的数据交互 那什么又是IO事件呢? 事件可以理解为一种状态或者动作,也就是状态的迁移会触发一种相应的动作。 网络IO的事件通常包括: 可读事件 可写事件 异常事件 理解可读可写事件是非常有必要的,一般来说一个socket大部分时候是可写的,但是并不是都可读。 可读一般代表是一个新连接或者原有连接有新数据交互,对于服务端程序来说也是重点关注的事件。 2.2 什么是IO复用 设想假如有几万个IO事件,那么应用程序该如何管理呢?这就要提到IO复用了。 IO复用从本质上来说就是应用程序借助于IO复用函数向内核注册很多类型的IO事件,当这些注册的IO事件发生变化时内核就通过IO复用函数来通知应用程序。 从图中可以看到,IO复用中复用的就是一个负责监听管理这些IO事件的线程。 之所以可以实现一个线程管理成百上千个IO事件,是因为大部分时间里某个时刻只有少量IO事件被触发。 大概就像这样: 草原上的一只大狗可以看管几十只绵羊,因为大部分时候只有个别绵羊不守规矩乱跑,其他的都是乖乖吃草。 3. 网络框架设计要素 要理解网络框架有哪些,必须要清楚网络框架完成了哪些事情。 大致描述下这个请求处理的流程: 远端的机器A发送了一个HTTP请求到服务器B,此时服务器B网卡接收到数据并产生一个IO可读事件; 我们以同步IO为例,此时内核将该可读事件通知到应用程序的Listen线程; Listen线程将任务甩给Handler线程,由Handler将数据从内核读缓冲区拷贝到用户空间读缓冲区; 请求数据包在应用程序内部进行计算和处理并封装响应包; Handler线程等待可写事件的到来; 当这个连接可写时将数据从用户态写缓冲区拷贝到内核缓冲区,并通过网卡发送出去; 备注:上述例子是以同步IO为例,并且将线程中的角色分为Listen线程、Handler线程、Worker线程,分别完成不同的工作,后续会详细展开。 所以我们可以知道,要完成一个数据交互,涉及了几大块内容: IO事件监听 数据拷贝 数据处理和计算 小林认为,这三大块内容,不论什么形式的框架都绕不开,也是理解网络架构的关键所在。 4. 高性能网络框架实践 4.1 基于线程模型 在早期并发数不多的场景中,有一种One Request One Thread的架构模式。 该模式下每次接收一个新请求就创建一个处理线程,线程虽然消耗资源并不多,但是成千上万请求打过来,性能也是扛不住的。 这是一种比较原始的架构,思路也非常清晰,创建多个线程来提供处理能力,但在高并发生产环境中几乎没有应用,本文不再展开。 4.2 基于事件驱动模型 当前流行的是基于事件驱动的IO复用模型,相比多线程模型优势很明显。 在此我们先理解一下什么是事件驱动Event-Drive-Model。 事件驱动编程是一种编程范式,程序的执行流由外部事件来决定,它的特点是包含一个事件循环,当外部事件发生时使用回调机制来触发相应的处理。 通俗来说就是: 有一个循环装置在一直等待各种事件的到来,并将到达的事件放到队列中,再由一个分拣装置来调用对应的处理装置来响应。 4.3 Reactor反应堆模式 第一次听到这个模式的时候很困惑,究竟反应堆是个啥? 研究了一下发现,反应堆是个核物理的概念,大致是这个样子的: 核反应堆是核电站的心脏 ,它的工作原理是这样的:原子由原子核与核外电子组成,原子核由质子与中子组成。 当铀235的原子核受到外来中子轰击时,一个原子核会吸收一个中子分裂成两个质量较小的原子核,同时放出2-3个中子。 这裂变产生的中子又去轰击另外的铀235原子核,引起新的裂变, 如此持续进行就是裂变的链式反应。 结合这种核裂变的图,好像 是一个请求打过来,服务器内部瞬间延伸出很多分支来完成响应,一变二,二变四,甚至更多,确实有种反应堆的感觉。 接下来我们看看究竟反应堆模式是如何构建高性能网络框架的。 5.反应堆模式详解 反应堆模式是一种思想,形式却有很多种。 5.1 反应堆模式的本质是什么 从本质上理解,无论什么网络框架都要完成两部分操作: IO操作:数据包的读取和写入 CPU操作:数据请求的处理和封装 所以上述这些问题 由谁来做以及多少线程来做,就衍生出了很多形式,所以不要被表面现象迷惑,出现必有原因,追溯之后我们才能真正掌握它。 反应堆模式根据处理IO环节和处理数据环节的数量差异分为如下几种: 单Reactor线程 单Reactor线程和线程池 多Reactor线程和线程池 我们来看看这三种常见模式的特点、原理、优缺点、应用场景等。 5.2 单Reactor线程模式 这种模式最为简洁,一个线程完成了连接的监听、接收新连接、处理连接、读取数据、写入数据全套工作。 由于只使用了一个线程,对于多核利用率偏低,但是编程简单。 是不是觉得这个种单线程的模式没有市场?那可未必,不信你看Redis。…

摩登3内部554258_和安卓说再见!华为手机鸿蒙OS 2.0来了!

今天上午,华为如约发布鸿蒙OS 2.0的手机开发者Beta版。同时面向开发者开启公测,华为P40 、P40 Pro、Mate 30、Mate 30 Pro、MatePad Pro等设备,抢先体验。 从媒体的现场体验来看,鸿蒙OS 2.0的手机开发者Beta版可兼容运行安卓应用,目前在UI设计上和基于安卓的EMUI11没什么区别,流畅度和EMUI 11相仿。 鸿蒙OS 2.0手机开发者Beta版 EMUI 11 也就是说,鸿蒙OS 2.0的手机开发者Beta版只是系统底层有所更改,原本底层是安卓,现在换成了鸿蒙,UI、UX与EMUI 11基本没有变化。 从曝光的鸿蒙OS 2.0的手机开发者Beta版“关于手机”界面来看,基本是EMUI 11的翻版。最大的不同是,前者显示HarmonyOS版本为11.0.1,没有了Android版本一栏。 按照华为此前规划,明年,华为智能手机将全面升级鸿蒙OS 2.0。据悉,升级EMUI 11的用户,将优先获得升级鸿蒙OS 2.0的机会。 以下为鸿蒙OS 2.0手机开发者Beta版界面: 来源:快科技

摩登3测速登陆_智慧需求大幅上涨,LED灯杆屏开启新路灯应用时代

在智慧路灯建设需求巨大的今天,LED灯杆屏的应用热度似乎从不褪减,几乎每一个智慧路灯项目都可见LED灯杆屏,开启全新路灯应用时代。 可以说,LED灯杆屏的出现,突破了路灯应用领域的常规化,在分分合合中实现了在应用领域的进一步深入。LED灯杆屏是安装在灯杆上的显示屏,是LED显示屏市场的一个细分领域。它是集数字化、网络化、信息化于一身的新一代媒体设备,能够为整个智慧路灯项目承载内容传播、碎片化应用和智能管理等要务。 然而,LED灯杆屏越来成为智慧路灯项目中不可缺少的配套应用,但是由于集成、成本等问题,LED灯杆屏价格是项目承包商较为关注的一个问题。 作为智慧灯杆产业中不可缺少并且作为重要配套应用——信息发布的LED灯杆屏,在目前许许多多的试点项目中得到了应用,并且开启了一场智慧显示的新浪潮。LED灯杆屏的配套应用更是为智慧灯杆的智慧管理带来更多的便利和提升更大的应用价值。 实际上,抛开产品本身不谈,红利爆发期对于LED灯杆屏厂家来说同样是一个考验和挑战,如何才能够在发展的洪流中站稳脚跟,聚势前行呢?对LED灯杆屏来说,这是一次重要的产业机遇,通过节点的升级改造以及传输技术的优化升级,LED灯杆屏在路灯领域的应用将会更加智能和节能,把应用体验再提升一个档次。 而让LED灯杆屏趋势席卷另一股重要力量就是5G商用的临近。5G商用时代的到来,助推了智慧灯杆产业的结构升级,无论是从硬件还是功能、业务上都会有很大的改变。LED灯杆屏在大市场、大跨界、大推动力的作用下更是承载更多的智慧价值,以信息化改造为亮点,以智能化升级为契机,以运营收益为“筹码”,进一步支撑智慧城市应用,呈现出新的竞争优势。 另一方面,LED灯杆屏作为智慧显示行业的“续航者”,起到了不可替代的作用,而智慧路灯产业多样化的架构也决定了其对于智慧的需求更具挑战性,LED灯杆屏各方面的演进正好符合这种需求。 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

摩登3注册登录网_干货分享!嵌入式裸机编程中使用malloc、free会怎样?

在嵌入式裸机编程中,作为一名初级的CODER。经常要与CPU、内存等打交道。CPU作为系统的动力源,其重要程度不言而喻。 但是,在裸机编程中,对内存的管理也不容忽视。如果稍微不注意,轻则,可能造成内存泄漏,重则造成内存访问异常。导致系统死机。 嵌入式产品,对稳定性要求及其严格。动不动就死机,那可就麻烦大了。以下,是我本人对嵌入式系统裸机编程的内存管理的一些简介。 1、尽量不使用库自带的malloc和free。 malloc和free在PC编程中是很好用的一种内存分配手段。但是,其在嵌入式中,就未必好用了。由于嵌入式裸机编程中,无MMU,即内存管理单元。无法实现对内存进行动态映射(不明白什么叫动态映射的同学,可以参考网上的资料)。 也就是说,实际上,malloc和free并不能实现动态的内存的管理。这需要在启动阶段专门给其分配一段空闲的内存区域作为malloc的内存区。如STM32中的启动文件startup_stm32f10x_md.s中可见以下信息: Heap_Size EQU 0x00000800AREA HEAP, NOINIT, READWRITE, ALIGN=3__heap_baseHeap_Mem SPACE Heap_Size__heap_limit 其中,Heap_Size即定义一个宏定义。数值为 0x00000800。Heap_Mem则为申请一块连续的内存,大小为 Heap_Size。简化为C语言版本如下: #define Heap_Size 0x00000800unsigned char Heap_Mem[Heap_Size] = {0}; 在这里申请的这块内存,在接下来的代码中,被注册进系统中给malloc和free函数所使用: __user_initial_stackheapLDR R0, = Heap_Mem ; 返回系统中堆内存起始地址LDR R1, =(Stack_Mem + Stack_Size)LDR R2, = (Heap_Mem + Heap_Size); 返回系统中堆内存的结束地址LDR R3, = Stack_MemBX LR 就如上面分析的那样,其实,在裸机编程的时候,对堆内存的管理。并非是智能化的,并非你想申请多少就多少。而是使用一块固定的内存用作堆内存的分配。这在设计的时候,往往不是最佳的方案。这块内存,如果被多次按照不同的大小进行申请,就会造成内存碎片。最终导致无法申请到足够的内存。导致系统运行出错。这在原本内存就已经很少的嵌入式系统中,更是不能接受的。所以,建议是把那个Heap_Size设置成 0 吧。放弃其使用吧。 而更为致命的是,有些malloc,free函数,由于工程人员的偷懒。实现甚至可能如下: unsigned char mem_buffer[512];unsigned char *mem_offset = & mem_buffer;void *malloc(int size){unsigned char *tmp = mem_offset; mem_offset += size;return (void *)tmp;}void free(void *mem){ mem_offset = mem;} 2、不用malloc、free的原因 一般单片机的内存都比较小,而且没有MMU,malloc 与free的使用容易造成内存碎片。而且可能因为空间不足而分配失败,从而导致系统崩溃,因此应该慎用,或者自己实现内存管理。如: 《一个简单而强大的单片机内存管理器》 在函数中使用malloc,如果是大的内存分配,而且malloc与free的次数也不是特别频繁,使用malloc与free是比较合适的,但是如果内存分配比较小,而且次数特别频繁,那么使用malloc与free就有些不太合适了。 因为过多的malloc与free容易造成内存碎片,致使可使用的堆内存变小。尤其是在对单片机等没有MMU的芯片编程时,慎用malloc与free。如果需要对内存的频繁操作,可以自己实现一个内存管理。 使用动态内存分配,应分不同的应用场合。 对于在操作系统上运行的程序,实际的物理内存分配与释放使用操作系统来实现的,即使程序调用了 malloc和free物理内存并不会马上变化。物理内存的变化,直到系统的内存管理操作时才发生。 对于裸机跑在MCU上的程序,分配与释放内存都会造成实际物理内存的变化。因为此时物理内存的分配是由自己实现的,而内存管理我们自己并没有去做。这样,盲目的使用malloc与free恰恰并不好,反而会造成内存的不恰当使用。甚至于内存溢出。 所以,动态内存的使用前提是有一套好的内存管理方法,这样动态内存的使用才会合理使用内存。如果没有合适的内存管理代码,还是用静态内存好一些。 可能有些同学,觉得:内存池,这是什么东西? 内存池,简洁地来说,就是预先分配一块固定大小的内存。以后,要申请固定大小的内存的时候,即可从该内存池中申请。用完了,自然要放回去。注意,内存池,每次申请都只能申请固定大小的内存。这样子做,有很多好处: (1)每次动态内存申请的大小都是固定的,可以有效防止内存碎片化。(至于为什么,可以想想,每次申请的都是固定的大小,回收也是固定的大小) (2)效率高,不需要复杂的内存分配算法来实现。申请,释放的时间复杂度,可以做到O(1)。 (3)实现简单,易用。 (4)内存的申请,释放都在可控的范围之内。不会出现以后运行着,运行着,就再也申请不到内存的情况。 内存池,并非什么很厉害的技术。实现起来,其实可以做到很简单。只需要一个链表即可。在初始化的时候,把全局变量申请来的内存,一个个放入该链表中。在申请的时候,只需要取出头部并返回即可。在释放的时候,只需要把该内存插入链表。以下是一种简单的例子(使用移植来的linux内核链表,对该链表的移植,以后有时间再去分析): #define MEM_BUFFER_LEN 5 //内存块的数量#define MEM_BUFFER_SIZE 256 //每块内存的大小//内存池的描述,使用联合体,体现穷人的智慧。就如,我一同学说的:一个字节,恨不得掰成8个字节来用。typedef union mem {struct list_head list;unsigned char buffer[MEM_BUFFER_SIZE];}mem_t;static union mem gmem[MEM_BUFFER_LEN];LIST_HEAD(mem_pool);//分配内存void *mem_pop(){ union mem *ret = NULL; psr_t psr; psr = ENTER_CRITICAL();…

摩登3注册网址_如何优雅地解决STM32的Flash写保护的问题?

本文介绍了如何解决STM32芯片Flash写保护导致无法下载程序,无法在线调试的问题;如果您遇到相同的问题,希望本文可以带来一些帮助; 1 FLASH的写保护 如果对Flash设置了写保护,那就无法对Flash进行编程和擦除。 在开发STM32的时候,如果出现这种情况,通常仿真器都支持对Flash进行解锁,像jlink,stlink等仿真器都支持这个功能。 2 错误提示 在使用MDK进行调试的时候,出现报错 ==Flash Timeout.Reset Target and try it again==,具体如下图所示; 折腾了一番之后,并没有解决问题,因为使用的仿真器是stlink,因此下载了stlink utility尝试解决问题; 3 stlink utility 3.1 基本功能 stlink utility是ST官方提供的免费软件,支持STM32 ST-LINK的程序包括带有命令行界面(CLI)的图形用户界面(GUI)。该工具还提供了较多的其他功能,具体如下; 可以对STM32 内部存储器 (Flash,RAM,OTP和其他存储器), 外部存储器进行编程; 验证程序内容(校验和,在编程期间和之后进行校验,与文件进行比较等) 还能实现 STM32编程自动化; 另外还提供其他的功能; 3.2 解锁Flash 在stlink连接目标板的情况下,打开stlink utility,在菜单栏的Target下选择connect,因为这时候Flash已经被锁住了,所以同样地也看到相应的错误提示 Can not read memory Disable Read Out Protection and retry,具体如下图所示; OK,下面只需要接触写保护就行了,所以在菜单栏target里打开Option Bytes…选项,或者直接通过快捷键ctrl+B打开,请确保当前已经正确连接了stlink和目标板,否则会出现报错; 正确连接的情况下,打开Option Bytes…,发现在这里Read Out Protection选项是enable,这个表示无法通过swd读取STM32内部Flash的程序。 关键点:将Read Out Protection选项设置为disable,点击Apply,这时候Flash已经成功解锁了。但是同时发现,内部Flash已经被擦除了; 这可能STM32的保护机制有关,防止程序被拷机,然后进行反编译破解,这样也可以提高破解的门槛。具体显示如下图所示; 完成以上步骤之后,在菜单栏Target下选择Disconnect,或者通过快捷键ctrl+D断开和目标板的连接;重新进入MDK,就能正常对目标板进行调试,仿真,以及程序的烧写。 3.3 写保护 在菜单栏target里打开Option Bytes…选项,我们还看到下面有Flash sector protection选项;选择Select all之后,发现所有Page都已经写保护了,只要选择apply选项就可以对Flash进行写保护;具体如下所示; 4 总结 对于Flash写保护的问题可以结合STM32参考手册进行相应的学习,其内部Flash提供相应的保护机制,本文只是结合ST官方工具stlink utility解决一下常见的这个简单的问题。 笔者能力和水平有限,文中难免有错误和纰漏之处,请大佬们不吝赐教; – END – 推荐好文   点击蓝色字体即可跳转  全网最通俗易懂SPWM入门教程,快来白嫖  天哪!原来PWM这么简单  PID微分器与滤波器的爱恨情仇  简易PID算法的快速扫盲 增量式PID到底是什么? 三面大疆惨败,因为不懂PID的积分抗饱和 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

摩登3平台首页_行业唯一!海信新风空调企业标准入选2020“领跑者”名单

12月19日,在京举办的2020年企业标准“领跑者”大会上,海信空调2项企业标准入选2020企业标准“领跑者”名单。其中,Q/0202RSR 683-2020《转速可控型新风房间空气调节器》为行业唯一入围的新风空调企业标准,也再次印证了海信在新风领域的领先实力。 相比于国家或团体标准,入选“领跑者”名单的企业标准更为苛刻。2020企业标准“领跑者”名单显示:海信空调共2项企业标准入选,涵盖33款新能效产品。其中,企业标准Q/0202RSR 683-2020《转速可控型新风房间空气调节器》为行业唯一入围的新风空调企业标准,其在新风量、噪声值、能效比等核心指标上,均在业内处于领先。 一流的企业做标准。事实上,今年3月由海信空调牵头制定了中国首个新风空调团标,规定了“新风空调器”的定义、产品分类、技术要求等。如今,海信再次用标准提高对新风空调的要求,引领行业回归到品质和价值追求的正确赛道上来。 今年以来,契合消费者健康需求,新风空调成大势所趋。中怡康线下监测数据显示:2020年1-50周,新风空调市场零售量、零售额同比增幅分别为186.6%,176.5%。而海信新风空调(第43-50周)零售额占比近3成,稳居行业TOP2,是标准和市场的双料领跑者。

摩登3注册登录网_线程间到底共享了哪些进程资源?

进程和线程这两个话题是程序员绕不开的,操作系统提供的这两个抽象概念实在是太重要了。 关于进程和线程有一个极其经典的问题,那就是进程和线程的区别是什么?相信很多同学对答案似懂非懂。 记住了不一定真懂 关于这个问题有的同学可能已经“背得”滚瓜烂熟了:“进程是操作系统分配资源的单位,线程是调度的基本单位,线程之间共享进程资源”。 可是你真的理解了上面最后一句话吗?到底线程之间共享了哪些进程资源,共享资源意味着什么?共享资源这种机制是如何实现的?对此如果你没有答案的话,那么这意味着你几乎很难写出能正确工作的多线程程序,同时也意味着这篇文章就是为你准备的。 逆向思考 查理芒格经常说这样一句话:“反过来想,总是反过来想”,如果你对线程之间共享了哪些进程资源这个问题想不清楚的话那么也可以反过来思考,那就是有哪些资源是线程私有的。   线程私有资源 线程运行的本质其实就是函数的执行,函数的执行总会有一个源头,这个源头就是所谓的入口函数,CPU从入口函数开始执行从而形成一个执行流,只不过我们人为的给执行流起一个名字,这个名字就叫线程。 既然线程运行的本质就是函数的执行,那么函数执行都有哪些信息呢? 在《函数运行时在内存中是什么样子》这篇文章中我们说过,函数运行时的信息保存在栈帧中,栈帧中保存了函数的返回值、调用其它函数的参数、该函数使用的局部变量以及该函数使用的寄存器信息,如图所示,假设函数A调用函数B: 此外,CPU执行指令的信息保存在一个叫做程序计数器的寄存器中,通过这个寄存器我们就知道接下来要执行哪一条指令。由于操作系统随时可以暂停线程的运行,因此我们保存以及恢复程序计数器中的值就能知道线程是从哪里暂停的以及该从哪里继续运行了。 由于线程运行的本质就是函数运行,函数运行时信息是保存在栈帧中的,因此每个线程都有自己独立的、私有的栈区。 同时函数运行时需要额外的寄存器来保存一些信息,像部分局部变量之类,这些寄存器也是线程私有的,一个线程不可能访问到另一个线程的这类寄存器信息。 从上面的讨论中我们知道,到目前为止,所属线程的栈区、程序计数器、栈指针以及函数运行使用的寄存器是线程私有的。 以上这些信息有一个统一的名字,就是线程上下文,thread context。 我们也说过操作系统调度线程需要随时中断线程的运行并且需要线程被暂停后可以继续运行,操作系统之所以能实现这一点,依靠的就是线程上下文信息。 现在你应该知道哪些是线程私有的了吧。 除此之外,剩下的都是线程间共享资源。 那么剩下的还有什么呢?还有图中的这些。 这其实就是进程地址空间的样子,也就是说线程共享进程地址空间中除线程上下文信息中的所有内容,意思就是说线程可以直接读取这些内容。 接下来我们分别来看一下这些区域。   代码区 进程地址空间中的代码区,这里保存的是什么呢?从名字中有的同学可能已经猜到了,没错,这里保存的就是我们写的代码,更准确的是编译后的可执行机器指令。 那么这些机器指令又是从哪里来的呢?答案是从可执行文件中加载到内存的,可执行程序中的代码区就是用来初始化进程地址空间中的代码区的。 线程之间共享代码区,这就意味着程序中的任何一个函数都可以放到线程中去执行,不存在某个函数只能被特定线程执行的情况。    数据区 进程地址空间中的数据区,这里存放的就是所谓的全局变量。 什么是全局变量?所谓全局变量就是那些你定义在函数之外的变量,在C语言中就像这样: char c; // 全局变量 void func() { } 其中字符c就是全局变量,存放在进程地址空间中的数据区。 在程序员运行期间,也就是run time,数据区中的全局变量有且仅有一个实例,所有的线程都可以访问到该全局变量。 值得注意的是,在C语言中还有一类特殊的“全局变量”,那就是用static关键词修饰过的变量,就像这样: void func(){ static int a = 10; } 注意到, 虽然变量a定义在函数内部,但变量a依然具有全局变量的特性 ,也就是说变量a放在了进程地址空间的数据区域, 即使函数执行完后该变量依然存在 ,而普通的局部变量随着函数调用结束和函数栈帧一起被回收掉了,但这里的变量a不会被回收,因为其被放到了数据区。 这样的变量对每个线程来说也是可见的,也就是说每个线程都可以访问到该变量。   堆区 堆区是程序员比较熟悉的,我们在C/C++中用malloc或者new出来的数据就存放在这个区域,很显然,只要知道变量的地址,也就是指针,任何一个线程都可以访问指针指向的数据,因此堆区也是线程共享的属于进程的资源。   栈区 唉,等等!刚不是说栈区是线程私有资源吗,怎么这会儿又说起栈区了? 确实,从线程这个抽象的概念上来说,栈区是线程私有的,然而从实际的实现上看,栈区属于线程私有这一规则并没有严格遵守,这句话是什么意思? 通常来说,注意这里的用词是通常,通常来说栈区是线程私有,既然有通常就有不通常的时候。 不通常是因为不像进程地址空间之间的严格隔离,线程的栈区没有严格的隔离机制来保护,因此如果一个线程能拿到来自另一个线程栈帧上的指针,那么该线程就可以改变另一个线程的栈区,也就是说这些线程可以任意修改本属于另一个线程栈区中的变量。 这从某种程度上给了程序员极大的便利,但同时,这也会导致极其难以排查到的bug。 试想一下你的程序运行的好好的,结果某个时刻突然出问题,定位到出问题代码行后根本就排查不到原因,你当然是排查不到问题原因的,因为你的程序本来就没有任何问题,是别人的问题导致你的函数栈帧数据被写坏从而产生bug,这样的问题通常很难排查到原因,需要对整体的项目代码非常熟悉,常用的一些debug工具这时可能已经没有多大作用了。 说了这么多,那么同学可能会问,一个线程是怎样修改本属于其它线程的数据呢? 接下来我们用一个代码示例讲解一下。   修改线程私有数据 不要担心,以下代码足够简单: void thread(void* var) { int* p = (int*)var; *p = 2;}int main() {    int a = 1; pthread_t tid; pthread_create(&tid, NULL, thread, (void*)&a); return 0;} 这段代码是什么意思呢? 首先我们在主线程的栈区定义了一个局部变量,也就是 int a= 1这行代码,现在我们已经知道了,局部变量a属于主线程私有数据,但是,接下来我们创建了另外一个线程。 在新创建的这个线程中,我们将变量a的地址以参数的形式传给了新创建的线程,然后我来看一下thread函数。 在新创建的线程中,我们获取到了变量a的指针,然后将其修改为了2,也就是这行代码,我们在新创建的线程中修改了本属于主线程的私有数据。 现在你应该看明白了吧,尽管栈区是线程的私有数据,但由于栈区没有添加任何保护机制,一个线程的栈区对其它线程是可以见的,也就是说我们可以修改属于任何一个线程的栈区。 就像我们上文说得到的,这给程序员带来了极大便利的同时也带来了无尽的麻烦,试想上面这段代码,如果确实是项目需要那么这样写代码无可厚非,但如果上述新创建线程是因bug修改了属于其它线程的私有数据的话,那么产生问题就很难定位了,因为bug可能距离问题暴露的这行代码已经很远了,这样的问题通常难以排查。   动态链接库 进程地址空间中除了以上讨论的这些实际上还有其它内容,还有什么呢? 这就要从可执行程序说起了。 什么是可执行程序呢?在Windows中就是我们熟悉的exe文件,在Linux世界中就是ELF文件,这些可以被操作系统直接运行的程序就是我们所说的可执行程序。 那么可执行程序是怎么来的呢? 有的同学可能会说,废话,不就是编译器生成的吗? 实际上这个答案只答对了一半。 假设我们的项目比较简单只有几个源码文件,编译器是怎么把这几个源代码文件转换为最终的一个可执行程序呢? 原来,编译器在将可执行程序翻译成机器指令后,接下来还有一个重要的步骤,这就是链接,链接完成后生成的才是可执行程序。 完成链接这一过程的就是链接器。 其中链接器可以有两种链接方式,这就是静态链接和动态链接。 静态链接的意思是说把所有的机器指令一股脑全部打包到可执行程序中,动态链接的意思是我们不把动态链接的部分打包到可执行程序,而是在可执行程序运行起来后去内存中找动态链接的那部分代码,这就是所谓的静态链接和动态链接。 动态链接一个显而易见的好处就是可执行程序的大小会很小,就像我们在Windows下看一个exe文件可能很小,那么该exe很可能是动态链接的方式生成的。 而动态链接的部分生成的库就是我们熟悉的动态链接库,在Windows下是以DLL结尾的文件,在Linux下是以so结尾的文件。…

摩登3内部554258_全球首款华为手机已经升级到鸿蒙了,先睹为快!!

华为在 2020-12-16 号发布了鸿蒙 beta 版,该版本支持手机。华为的大多数机型都可以升级到鸿蒙。 正好我手头有几部华为 P40 的手机,而且都收到了鸿蒙的推送,现在就来先睹为快吧。 首先进入到设置页面,点击“系统和更新”→ “软件更新”,系统会自动检测鸿蒙的最小版本,目前最新的版本是 2.0.0 Developer Beta1,然后可以点击开始刷机按钮(会弹出一个对话框)。 鸿蒙升级版有 4 个多 G,建议用快递的宽带,例如,我家里的是 500G 宽带,下载完大概 10 分钟左右,速度还是比较快的。开始安装后就会重启,然后速度还是很快滴。 如下图,很快就会到 100%: 接下来就会重启手机: 重启后,一切就搞定了。先上图。这就是鸿蒙桌面的首页,看着还很清爽的。速度也很快。 下面来看一下鸿蒙的版本,妥妥滴 HarmonyOS。这是真正的鸿蒙系统。 再看看内核版本,HarmonyOS,看图: 最后,来试试最新的鸿蒙系统是否可以运行我们开发的程序,打开最新版的 DevEco Studio,创建一个 Phone 工程。 按下图选择: 然后选择的 API 版是 4,如下图: 最后点击 Finish 创建工程。别忙,要想在手机上运行,还需要签名,点击 Project Structure 菜单项,进入到 Modules 的签名页面,如下图。 由于这里只进行调试,所以只设置 debug 签名即可,这里面涉及到 3 类文件:p12、p7b 和 cer。这些文件如何获得,后期我会单独制作完整的鸿蒙开发视频课程来讲解。 配置完签名后,直接运行,就会在鸿蒙手机上安装并自动运行了,如下图: ok,剩下的时间就交给各位了,尽情滴享受鸿蒙吧(前提是要有华为手机,而且收到了鸿蒙的推送,good luck)! END 来源:鸿蒙技术社区 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

摩登三1960_中国移动内蒙古公司联合中兴通讯完成SSB1+X立体覆盖方案验证

近日,中国移动内蒙古公司联合中兴通讯在内蒙古通辽完成SSB1+X立体覆盖方案验证。该方案能够有效改善现阶段高层楼宇深度覆盖不足的问题。通过验证,在20层以上的高楼用户平均信号强度增加了5.8dB,下载速率平均提升了106Mbps,提升效果显著,为高层楼宇室内覆盖难点提供了全新的解决方案。 随着内蒙古移动5G建设的不断发力,目前已实现各地市城区道路的基本覆盖。但是如何利用现有宏站加强室内用户的5G渗透率,提升室内5G用户感知是目前面临的一个重要问题。尤其是针对高楼层用户,在室分系统暂未建设的情况下显得尤为重要。 针对当前所面临的问题,内蒙古移动联合中兴通讯在通辽开展了SSB1+X立体覆盖方案的验证,通过1个SSB水平增强型宽波束+X个SSB垂直可变波束来达到高层楼宇的立体覆盖效果,增强高层楼宇的深度覆盖。验证结果显示,20层以上测试SSB-RSRP平均增加5.8dB,SSB-SINR平均增加8dB,用户下载速率平均提升106Mbps,网络质量提升效果显著。该方案具有:增益大、省资源、降能耗、易演进、部署简单等优势。通过对场景的简单分析即可完成部署,加强了网络立体覆盖能力。 在5G加速发展的大时代下,内蒙古移动将继续联合中兴通讯等设备厂商,不断探索、应用最前沿的科学技术,为广大用户提供优质、稳定、可靠的5G网络服务。