首页 文章 精选 留言 我的

精选列表

搜索[VSCode扩展],共10000篇文章
优秀的个人博客,低调大师

Unity C#基础之 多线程的前世今生(下) 扩展篇

在前面两篇Unity C#基础之 多线程的前世今生(上) 科普篇和Unity C#基础之 多线程的前世今生(中) 进阶篇中,相信大家对多线程有了一定的了解,这篇再详细的聊一聊在使用多线程中需要注意的地方~ 示例工程下载Unity 2017.3.0 P4 .NET版本4.6 本篇知识点 异常处理 线程取消 CancellationTokenSource 多线程临时变量 线程安全 lock 语法糖 await async 异常处理 首先我们先执行下面一段代码 循环20次用Task线程执行以下Code,当执行循环 i=11 或 i=12时抛出异常 打印信息中没有 11、12的打印信息,也没有抛出异常的信息,这是因为主线程的Trycatch已经跳过 然后我们在try块中添加 Task.WaitAll(taskList.ToArray()); 打印信息如下 出现抛出异常信息 然后我们去掉try块中的 Task.WaitAll(taskList.ToArray()); 在每个线程中添加Try Catch 打印结果可以捕捉到异常 所以要想捕捉到异常且不卡界面,捕捉异常最好在每个自己的线程中捕捉 相应的全部Code private void TryCatchOnClick() { System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Start(); Debug.Log($"TryCatchOnClick Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}"); try { TaskFactory taskFactory = new TaskFactory(); List<Task> taskList = new List<Task>(); #region 异常处理 //多线程里的异常是会被吞掉,除非waitall // 建议 多线程里面,是不允许异常的,也就是内部try catch,自己处理好 for (int i = 0; i < 20; i++) { string name = string.Format($"TryCatchOnClick{i}"); Action<object> act = t => { try { Thread.Sleep(2000); if (t.ToString().Equals("TryCatchOnClick11")) { throw new Exception(string.Format($"{t} 执行失败")); } if (t.ToString().Equals("TryCatchOnClick12")) { throw new Exception(string.Format($"{t} 执行失败")); } Debug.Log($"{t} 执行成功"); } catch (Exception ex) { Debug.Log(ex.Message); } }; taskList.Add(taskFactory.StartNew(act, name)); } //Task.WaitAll(taskList.ToArray()); #endregion } catch (AggregateException aex) { foreach (var item in aex.InnerExceptions) { Debug.Log(item.Message); } } catch (Exception ex) { Debug.Log(ex.Message); } watch.Stop(); Debug.Log($"TryCatchOnClick End {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}"); } 线程取消 某个线程达到预期效果后需要取消其他的线程,我们可以用 CancellationTokenSource,当然可以用一个共享的bool变量,但是CancellationTokenSource的好处是可以让没来的及启动的线程直接取消,从根本上取消启动 private void TaskCancel() { System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Start(); Debug.Log($"TaskCancel Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}TaskCancel"); try { TaskFactory taskFactory = new TaskFactory(); List<Task> taskList = new List<Task>(); //线程取消不是操作线程,而是操作信号量(共享变量,多个线程都能访问到的东西,变量/数据库的数据/硬盘数据) //每个线程在执行的过程中,经常去查看下这个信号量,然后自己结束自己 //线程不能别人终止,只能自己干掉自己,延迟是少不了的 //CancellationTokenSource可以在cancel后,取消没有启动的任务 CancellationTokenSource cts = new CancellationTokenSource();//bool值 for (int i = 0; i < 200; i++) { string name = string.Format("btnThreadCore_Click{0}", i); Action<object> act = t => { try { Thread.Sleep(2000); if (t.ToString().Equals("btnThreadCore_Click11")) { throw new Exception(string.Format("{0} 执行失败", t)); } if (t.ToString().Equals("btnThreadCore_Click12")) { throw new Exception(string.Format("{0} 执行失败", t)); } if (cts.IsCancellationRequested)//检查信号量 { Debug.Log($"{t} 放弃执行"); return; } else { Debug.Log($"{t} 执行成功"); } } catch (Exception ex) { cts.Cancel(); Debug.Log(ex.Message); } }; taskList.Add(taskFactory.StartNew(act, name, cts.Token)); } Task.WaitAll(taskList.ToArray()); } catch (AggregateException aex) { foreach (var item in aex.InnerExceptions) { Debug.Log(item.Message); } } catch (Exception ex) { Debug.Log(ex.Message); } watch.Stop(); Debug.Log($"TaskCancel End {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}"); } 打印结果如下 多线程临时变量 这个就比较简单了,直接上Code private void TaskTempVariable() { System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Start(); Debug.Log($"TaskTempVariable Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}"); try { TaskFactory taskFactory = new TaskFactory(); List<Task> taskList = new List<Task>(); ////i 只有一个,真实实行的时候,已经是5了, ////k 多个k,每次是独立的k,跟i没关系 ////int k; for (int i = 0; i < 5; i++) { int k = i; new Action(() => { Thread.Sleep(1000); Debug.Log($"对应的数值K:{k}"); Debug.Log($"对应的数值I:{i}"); }).BeginInvoke(null, null); } Task.WaitAll(taskList.ToArray()); } catch (AggregateException aex) { foreach (var item in aex.InnerExceptions) { Debug.Log(item.Message); } } catch (Exception ex) { Debug.Log(ex.Message); } watch.Stop(); Debug.Log($"TaskTempVariable End {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}"); } 打印结果 线程安全 lock ConcurrentDictionary多线程版字典 多线程1000次操作一个int和List private static readonly object StaticAsyncLock = new object(); private int TotalCount = 0;// private List<int> IntList = new List<int>(20000); private void TaskSafe() { System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Start(); Debug.Log($"TaskSafe Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}"); try { TaskFactory taskFactory = new TaskFactory(); List<Task> taskList = new List<Task>(); //共有变量:都能访问局部变量/全局变量/数据库的一个值/硬盘文件 //线程内部不共享的是安全 //解决多线程冲突第一个办法:lock ,lock的方法块儿里面是单线程的,所以将整个方法Lock多线程将变得毫无意义;lock里面的代码要尽量的少 //解决多线程冲突第二个办法:没有冲突,从数据上隔离开 for (int i = 0; i < 10000; i++) { int TempI = i; taskList.Add(taskFactory.StartNew(() => { lock (StaticAsyncLock)//lock后的方法块,任意时刻只有一个线程可以进入语法糖 lock(StaticAsyncLock) 编译后等于 Monitor.Enter(StaticAsyncLock) { //这里就是单线程 this.TotalCount += 1;//多个线程同时操作,有时候操作被覆盖了 IntList.Add(TempI); } })); //语法糖 lock(StaticAsyncLock) 编译后等于 Monitor.Enter(StaticAsyncLock) Monitor.Exit(StaticAsyncLock) //检查下这个变量(引用) 有没有被lock 有就等着,没有就占用,然后进去执行,执行完了释放 //lock(this) 锁定当前实例,别的地方如果要使用这个实力里面的其他变量,则都被锁定了无法使用(不推荐这么写) //如果每个实例想要单独的锁定 private object //string a="123456" lock(a) string b="123456" 享元模式的内存分配,字符串值是唯一的,会锁定别的变量b //private static readonly object StaticAsyncLock = new object(); } Task.WaitAll(taskList.ToArray()); Debug.Log(this.TotalCount); Debug.Log(IntList.Count); } catch (AggregateException aex) { foreach (var item in aex.InnerExceptions) { Debug.Log(item.Message); } } catch (Exception ex) { Debug.Log(ex.Message); } watch.Stop(); Debug.Log($"TaskSafe End {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}"); } 添加Lock锁前后打印结果 语法糖 await async (C#5.0 .NET 4.5 CLR 4.0) 如果用一句话简单概括await async,那就是:多线程版的协程 先来一个简单的示例,做一个大象装冰箱,最后咱们再详细的分析 打印结果 是不是很有趣?这种书写逻辑基本上和原来的协程一样,而且是真正的多线程,但是依据不能运行UnityEngine中的组件(例如:GameObject),下面我们详细的说一说 await async 第一个示例 在基础的方法上添加关键字 async 根据提示只有aysnc没有await 会有一个警告,跟普通方法没有区别(不得不说VS2017还是很不错的,提示、自动修补都很友好) 打印结果 第二个是示例 在第一个示例的基础上添加await关键字,这时当主线程到达await task时就返回了,继续执行方法外部的函数,可以理解为unity协程中的yeild reture,当task的线程块执行完毕后再回调 awati task后面的函数部分,这个回调的线程是不确定的:可能是主线程 可能是子线程 也可能是其他线程 /// <summary> /// async/await /// 不能单独await /// await 只能放在task前面 /// 不推荐void返回值,使用Task来代替 /// Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用。Async Void 不行 /// </summary> private async void NoReturn() { //主线程执行 Debug.Log($"NoReturn Sleep before await,线程ID:{Thread.CurrentThread.ManagedThreadId}"); TaskFactory taskFactory = new TaskFactory(); Task task = taskFactory.StartNew(() => { Debug.Log($"多线程 Sleep before,线程ID:{Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(3000); Debug.Log($"多线程 Sleep after,线程ID:{Thread.CurrentThread.ManagedThreadId}"); }); await task;//主线程到这里就返回了,执行主线程任务 //子线程执行 其实是封装成委托,在task之后成为回调(编译器功能 状态机实现) //task.ContinueWith() //这个回调的线程是不确定的:可能是主线程 可能是子线程 也可能是其他线程 Debug.Log($"NoReturn Sleep after await,线程ID:{Thread.CurrentThread.ManagedThreadId}"); } 打印结果 第三个示例,如果需要获取这个返回的线程怎么办呢?直接把void 换成Task /// <summary> /// 无返回值 async Task == async void /// Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用。Async Void 不行 /// </summary> /// <returns></returns> private async Task NoReturnTask() { //这里还是主线程的id Debug.Log($"NoReturnTask Sleep before await,线程ID:{Thread.CurrentThread.ManagedThreadId}"); await Task.Run(() => { Debug.Log($"多线程 Sleep before,线程ID:{Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(9000); Debug.Log($"多线程 Sleep after,线程ID:{Thread.CurrentThread.ManagedThreadId}"); }); Debug.Log($"NoReturnTask Sleep after await,线程ID:{Thread.CurrentThread.ManagedThreadId}"); //return new TaskFactory().StartNew(() => { }); //不能return 没有async才行 } 然后执行 打印结果 第四个示例,也是最终版的示例 返回线程+返回数值 ,获取一个Task<T> ,其中T就是返回值的类型 /// <summary> /// 带返回值的Task /// 要使用返回值就一定要等子线程计算完毕 卡线程 /// </summary> /// <returns>async 就只返回long</returns> private async Task<long> FinallyAsync() { Debug.Log($"SumAsync start 线程ID:{Thread.CurrentThread.ManagedThreadId}"); long result = 0; await Task.Run(() => { Debug.Log($"SumAsync await Task.Run 线程ID:{Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(1000); for (long i = 0; i < 999999999; i++) { result += i; } }); return result; } 然后执行 打印结果 非await版返回值 这种主线程获取result不会卡死 /// <summary> /// 真的返回Task 不是async /// /// 要使用返回值就一定要等子线程计算完毕 /// </summary> /// <returns>没有async Task</returns> private Task<int> TaskReturn() { Debug.Log($"TaskReturn start 线程ID:{Thread.CurrentThread.ManagedThreadId}"); TaskFactory taskFactory = new TaskFactory(); Task<int> iResult = taskFactory.StartNew<int>(() => { Thread.Sleep(3000); Debug.Log($"TaskReturn Task.Run 线程ID:{Thread.CurrentThread.ManagedThreadId}"); return 123; }); Debug.Log($"TaskReturn end 线程ID:{Thread.CurrentThread.ManagedThreadId}"); return iResult; } 执行函数 打印结果 以上就是await async 的相关内容,有需要补充的东西欢迎留言

优秀的个人博客,低调大师

解决Centos7 下安装PHP7 phpredis扩展报错办法

heckingwhether-lcshouldbeexplicitlylinkedin...no checkingdynamiclinkercharacteristics...GNU/Linuxld.so checkinghowtohardcodelibrarypathsintoprograms...immediate checkingwhetherstrippinglibrariesispossible...yes checkingiflibtoolsupportssharedlibraries...yes checkingwhethertobuildsharedlibraries...yes checkingwhethertobuildstaticlibraries...no creatinglibtool appendingconfigurationtag"CXX"tolibtool configure:creating./config.status config.status:creatingconfig.h [root@iZ236oj5mp5Zphpredis-master]#make&&makeinstall /bin/sh/usr/local/src/redis-stable/phpredis-master/libtool--mode=compilecc-I.-I/usr/local/src/redis-stable/phpredis-master-DPHP_ATOM_INC-I/usr/local/src/redis-stable/phpredis-master/include-I/usr/local/src/redis-stable/phpredis-master/main-I/usr/local/src/redis-stable/phpredis-master-I/usr/local/php/include/php-I/usr/local/php/include/php/main-I/usr/local/php/include/php/TSRM-I/usr/local/php/include/php/Zend-I/usr/local/php/include/php/ext-I/usr/local/php/include/php/ext/date/lib-DHAVE_CONFIG_H-g-O2-c/usr/local/src/redis-stable/phpredis-master/redis.c-oredis.lo mkdir.libs cc-I.-I/usr/local/src/redis-stable/phpredis-master-DPHP_ATOM_INC-I/usr/local/src/redis-stable/phpredis-master/include-I/usr/local/src/redis-stable/phpredis-master/main-I/usr/local/src/redis-stable/phpredis-master-I/usr/local/php/include/php-I/usr/local/php/include/php/main-I/usr/local/php/include/php/TSRM-I/usr/local/php/include/php/Zend-I/usr/local/php/include/php/ext-I/usr/local/php/include/php/ext/date/lib-DHAVE_CONFIG_H-g-O2-c/usr/local/src/redis-stable/phpredis-master/redis.c-fPIC-DPIC-o.libs/redis.o Infileincludedfrom/usr/local/src/redis-stable/phpredis-master/redis.c:27:0: /usr/local/src/redis-stable/phpredis-master/common.h:3:40:致命错误:ext/standard/php_smart_str.h:没有那个文件或目录 #include<ext/standard/php_smart_str.h> ^ 编译中断。 make:***[redis.lo]错误1 解决办法,因为最新的 phpredis 分了几大分支,针对最新的PHP稳定发行版 php7 有专门为php7的分支,所以我们从github拉下phpredis 源码 需要切换到 PHP7的分支 首先git clone phpredis : git clone https://github.com/nicolasff/phpredis git checkout php7 /usr/local/php7/bin/phpize ./configure --with-php-config=/usr/local/php/bin/php-config make && make install 然后看到了等字样,就说明安装成功了

优秀的个人博客,低调大师

centos6.5环境 安装php5.5.30的redis扩展

1、下载软件包 wget http://pecl.php.net/get/redis-2.2.5.tgz 2、解压 tar zxvf redis-2.2.5.tgz 3、进入安装目录 cd redis-2.2.5 4、用phpize生成configure配置文件 /usr/local/php/bin/phpize 5、配置(填写php的配置文件路径) ./configure --with-php-config=/usr/local/php/bin/php-config 6、编译 make 7、安装 make install 安装完成之后,出现下面的安装路径 /usr/local/php-5.5.30/lib/php/extensions/no-debug-non-zts-20121212/ ls一下,可以看到.so的文件 然后组装一下地址: /usr/local/php-5.5.30/lib/php/extensions/no-debug-non-zts-20121212/redis.so 8、配置php支持 vi /usr/local/php/etc/php.ini 添加 extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20121212/redis.so 9、开启php、redis、nginx 10、测试 $redis=new Redis(); $redis->connect("192.168.1.128",6379); $redis->set("username","zhangsan"); echo $redis->get("user:userid:10:username"); $redis->lpush("list","helloWorld"); $redis->lpush("list","goodMorning"); $redis->lpush("list","what"); $list=$redis->lrange("list",0,-1); print_r($list); 测试正常

优秀的个人博客,低调大师

服务器架构之性能扩展-第八章(9)

第八章:Sphinx全文检索 8.1检索简介 生活中总会和数据打交道,数据一般分为结构化数据(具有自动固定格式或有限长度数据)和非结构化数据,非结构化数据又称全文数据。 全文索引的扫描大致分为索引的创建和搜索索引两个过程。 索引创建:将现实世界的所有结构化数据和非结构化数据提取信息,建立索引的过程。 索引搜索:就是得到用户的查询请求,搜索创建的索引,返回结果的过程。 创建索引具体过程: 1、首先创建需要索引的文档 2、将源文档传给分词词组(tokenizer)。分词词组会将文档分成一个一个的单独单词,去掉标点,去掉停词(的,这等) 3、将的得到的词元(token)传给语言处理组件(linguistic processor)。它主要进行单词变为小写,复数改为单数(cars->car),过去式转给原始等。 4、将得到的词(term)传给索引组件(indexer)。它进行创建一个字典,并按字母排序。 索引搜索具体过程: 1、用户输入查询语句 2、对查询语句进行语法分析,语言处理 3、搜索索引,得到合法树的文档 4、根据得到的文档和查询语句的相关性,进行排序 8.2sphinx入门 Sphinx是SQL phrase index(查询词组索引)的缩写,sphinx是一个基于SQL的全文检索引擎。Coreseek是支持中文的全文检索引擎。 用处:当数据的量增大对搜索有更高要求时;当用户放映搜索慢时;当需要设计千万级亿级别的架构时 Sphinx优点:检索速度快,对于2-4G数据只要0.1秒,提供分布式搜索,可以为mysql提供检索,支持多个检索字段 缺点:必须有主键,主键为整形,不负责数据存储,配置不灵活 Sphinx全文索引工作在php和mysql之间,完成数据的检索。 8.3 sphinx的部署 8.3.1 sphinx的安装 Wgethttp://www.sphinxsearch.com/downloads/sphinx-0.9.9.tar.gz Tar zxvf sphinx-0.9.9.tar.gz Cd sphinx-0.9.9 ./configure –prefix=/usr/local/sphinx –with-mysql=/usr/local/mysql Make && make install 这时在sphinx/bin目录下会有三个命令。Indexer:创建索引;seachd:启动进程;seach:搜索命令。 我们创建一个主键为整形的表,添加数据。 8.3.2配置sphinx 安装完毕会在sphinx/etc目录下生成一个sphinx.conf.disk的示例配置,修改即可。这个配置文件包括朱数据源文件,增量数据文件,主索引,增量索引,所引器和服务进程组成的。 1、主数据源是源数据,后期添加数据为增量数据源 Source src1改为source main作为主数据源,然后配置数据库信息 指定socket位置 设置mysql字符集,关闭缓存 指定数据sql语句 注释掉这些默认的信息 更改查询的数据库 注释主数据索引 指定字符集 注释增量索引。 :494,525s/^/#/g//批量注释分布式索引 索引器设置内存,默认32MB 服务器进程设置端口,默认即可 8.3.3测试 /usr/local/sphinx/bin/bin/indexer –c /usr/local/sphinx/etc/sphinx.conf –all -c指定配置文件,--all对所有索引重新编译 Cp /usr/local/mysql/lib/mysql/libmysqlclient.so.16 /usr/lib ./search linux//测试 新插入数据后直接搜索还是搜不到,只有重新索引后才可。 insert into saisai values(5,”spider”,”斯百德”); //插入中文,测试中文索引 测试不通过 8.4coreseek中文索引部署 8.4.1安装coreseek Sphinx默认是不支持中文的,我们需要引入coreseek进行中文索引,因为它包含了mmseg中文分词组件。 Wgethttp://www.coreseek.cn/uploads/csft/4.0/coreseek-4.1-beta.tar.gz Tar zxvf coreseek-3.2.14.tar.gz 解压后,分别是sphinx文件csft和中文字符文件mmseg,说明文件和链接文件 Cd coreseek-3.2.14/mmseg//先安装中文分词,然后整合进去 ./configure –prefix=/usr/local/mmseg 会报错:config.status: error: cannot find input file: src/Makefile.in automake//执行automake,自动配置环境 接下来sphinx和mmseg结合 Cd coreseek-3.2.14/csft-3.2.14/ ./configure --prefix=/usr/local/coreseek --with-mysql=/usr/local/mysql --with-mmseg-includes=/usr/local/mmseg/include/mmseg/ --with-mmseg-libs=/usr/local/mmseg/lib/ 最后:Make && make install 8.4.2配置coreseek Cp /usr/local/csft/etc/sphinx.conf.disk/usr/local/csft/ect/csft.conf 与sphinx其他都一样,只要在main主数据文件“#charset_type=sbcs” 后增加“charset_type=zh_cn.utf-8”和“charset_dictpath=/usr/local/mmseg/etc”指定字符集和mmseg安装目录即可 然后重新刷新索引进行测试即可,还可以看到他还识别词组 8.5中文分词 对于英文字符间有空格比较直观,而中文却不行。并且中文拥有一些容易歧义的语句,更是增加了难度。 分词的算法: 1、基于字符串匹配的分词方法:它是基于词典的分词方法。有正向,逆向和双向的顺序,又有最大,最小,逐词和最佳。 2、基于理解的分词方法:人机模拟,目前测试阶段 3、基于统计的分词方法:根据概率来的 8.6php使用sphinx技术 Sphinx集成到php需要两种方式: 1.sphinx php模块 2.sphinxapi类 8.6.1sphinx模块 到/csf-3.12.12/api下可以看到sphinxapi.php模块 要想在php程序中开启sphinx必须启动sphinx服务,到/usr/local/coreseek/bin下有searchd命令,可以控制sphinx。 参数:-c指定配置文件,--stop停止服务,--pidfile指定pid文件,-p指定端口 Wgethttp://pec1.php.net/get/sphinx-1.1.0.tgz Tar zxvf sphin-1.1.0.tgz Cd sphin-1.1.0 /usr/local/php/bin/phpize//加载模块 ./configure –with-php-config=/usr/local/php/bin/php-config//报错 我们先安装cd core-3.2.14/csf-3.214/api/libclient ./configure Make && make install 然后cd sphinx-1.1.0 ./configure –with-php-config=/usr/local/php/bin/php-config Make && make install cd/usr/local/php5/lib/php/extensions/no-debug-zts-20090626/ Vi /etc/php.ini//加载sphinx.so模块 /usr/local/apache2/bin/apachectl restart//重启apache 192.168.211.128/info.php//看到sphinx模块 8.6.2sphinx类方法 Cp coreseek-3.2.14/csf-3.2.14/api/sphinxapi.php /usr/local/apache2/htdocs/include/sphinxapi.php//加载类 8.6.3搭建windows的linux编程环境 Yum install samba* 配置samba 复制home的选项,新建一个web的目录,重启服务 创建一个smb用户 开始-》运行-》\\192.168.211.128\web 创建磁盘映射,计算机->映射网络驱动器 确定即可创立一个映射磁盘 插入数据拒绝 我们知道apache使用apache用户,我们最好让映射磁盘也使用apache用户,这样可以保证windows下创建的文件可以直接访问。 Net usr /delete *//删除磁盘映射 创建新的用户,我们使用新的apache用户登录 创建文件可以看到是apache用户 这样就实现了windows和linux的同步。 传一个数据过来,建立一个新的sphinx客户端,连接到9312端口,any和all两种,any这里选择是任意的,all是指只包含,通过query搜索关键词,*任意索引,至此得到文档id。 本文转自zsaisai 51CTO博客,原文链接:http://blog.51cto.com/3402313/989242

优秀的个人博客,低调大师

服务器架构之性能扩展-第四章(5)

第四章、MYSQL主从复制和分区技术 Mysql作为web数据库,对于越来越大的数据存储,主从复制、分区技术和SQL语句优化,对于提高访问量有很大的帮助。 4.1mysql用户授权 主服务器首先对远程服务器建立一个授权用户,可以在从服务器上登录主服务器的数据库。 Mysql〉grant all on *.* touser@192.168.10.2identified by "123"; Mysql>use mysql Mysql>select user,password,host from user;//查看用户情况 测试:从服务器登陆,可以看到内容和主服务器是一样的 4.2 mysql bin-log日志 Mysql的bin-log日志是记录与数据的增删改查有关的数据库语句。于是bin-log可以作为数据库恢复的文件来使用,也是mysql能够主从复制的基础。 4.2.1开启mysql的bin-log日志 Vi /etc/my.cnf Log-bin=mysql-bin//增加这个语句,重启mysql即可 4.2.2查看是否开启bin-log: Mysql>show variables like ‘%bin%’; 1.2.3.mysql的bin-log日志管理 mysql>flush logs;//此时就会多一个新的bin-log日志 mysql>show master status;//查看目前使用的bin-log日志 mysql>reset master;//清空所有日志 4.2.4用bin-log进行数据的备份和恢复 备份数据库:测试数据库名为test,表为t。 Mysqldump –uroot –p test –l –F > ‘/tmp/test.sql’ -L锁定表,-F是刷新bin-log日志,这样便可以用刷新之前的日志进行恢复到备份时刻 Mysql>insert into t values(1);//插入新纪录 Mysq>flush logs; Mysql>drop table t;//删除表 恢复数据库 Mysql test </tmp/test.sql 如果要恢复数据库备份后那段时间的记录,就需要恢复bin-log日志 Mysqlbinlog mysql-00002.bin |mysql –uroot –p test 下图是bin-log的日志内容我们可以看到它是包含position点的。恢复日志也可以指定position点。--stop-position=“193”. 4.3mysql主从复制 Mysql主从复制的优点: 1.如果主服务器出现问题,可以快速切换到从服务器提供服务 2.可以在从服务器上执行查看操作,降低主服务器的访问压力 3.可以在从服务器上执行备份,以避免备份期间影响主服务器的服务 4.3.1Mysql主服务器的配置: Mysql>grant all slave on *.* tosaisai@192.168.10.2identified by “123”; Vi /etc/my.cnf Log-bin=mysql-bin//开启log-bin功能 Server-id=1//指定server ID Service mysql restart Mysql>show master status;//查看是否开启和bin ID 4.3.2mysql从服务器的配置 Vi /etc/my.cnf 指定主服务器ip和server id(这里id要不为1),以及主服务器的端口和连接主服务器的用户名和密码,开启bin-log,然后重启mysql服务器,同步之前要确保主从服务器有相同的数据库名和表结构。 Mysql>show slave status\G 这里要保证两个yes选项,第一个slave_io_running为yes表示可以成功从主服务器上读取binlog日志并写入从服务上,第二个slave_Sql_running为yes表示可以成功读取本机binlog日志同步数据。可以看到它们也具有相同的bin-log。 如果数据无法同步: 如果是slave_io_running失败,要检查一下从数据库能否登陆主数据,然后检查从数据库是否和主数据有一致的数据库和表结构。 如果是slave_sql_running失败,要检查从服务是否启动和配置文件。 如slave stop;set global sql_slave_skip_counter=1;slave start. 4.4Mysql表分区 4.4.1分区技术简介 当mysql的数据记录超过千万或上亿条纪录时,数据的性能会出现下降,这时就要用到分表分区技术或优化sql语句的方法来提高数据库的使用效率。 分表技术通常有垂直分表和水平分表,垂直分表是对数据库字段进行分表;水平分表是对数据记录进行分表。垂直分表技术复杂,不易操作,水平分表更常用。 水平分表可以将一个表分成多个表,但是如果多个表使用不同的表名,则查询语句要更改,于是引入了分区分表的概念,它不改变表名。 分区分表是在逻辑层进行水平分表,对与应用程序而言,它依然是一张表。Mysql5.1中,它有5钟分区类型: 4.4.2分区技术类型 Range分区:基于属于一个给定的连续区间的列值,把匹配的多行分配给相应分区 List分区:类似range分区,区别在于list分区是基于列值匹配一个离散值集合中的某个值来进行选择 Hash分区:基于用户定义的表达式的返回值进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算,这个函数可以包含mysql中有效的,产生非负整数值的任何表达式 Key分区:类似于hash分区,区别在于key分区只支持计算一列或多列,且mysql服务器提供其自身的哈希函数 查看mysql的版本信息:mysql>status; 查看是否支持分区技术:mysql>show plugins;//看到partion选项 4.4.3range分区技术 例1:假定如下的表,该表有20加音像店的职员记录,这二十家的音像编号从1到20,如果采用range分区为4个小分区,如何实现呢? Mysql>create table employees( >id int not null, >fname varchar(30), >lname varchar(30), >hired date not null default ‘1970-01-01’, >separated date not null default ‘9999-12-31’, >job_code int not null, >store_id int not null >) >partition by range(store_id)( >partition p0 values less than(6), >partition p1 values less than(11), >partition p2 values less than(16), >partition p3 values less than(21), >); 根据store_id(店号)进行分区,less than根据店号ID进行分区。 如果要按离职时间进行分区可以使用: >partition by range(year(separated))( >partition p0 values less than(1991), >partition p1 values less than(1996), >partition p2 values less than(2001), >partition p3 values less than maxvalue, >);//使用year()函数转为整形 4.4.4 list分区技术 List分区类似于range分区,但他是根据离散值来分区。 例3.还是该表保存有20家音像店,编号从1到20,而这20家音像店分布在四个区域: >partition by list(store_id)( >partition pnorthvalues in (3,5,6,9,17), >partition peast values in(1,2,10,11,19,20), >partition pwest values in(4,12,13,14,18), >partition pcentral values in( 7,8,15,16), >); 4.4.5hash分区技术 Hash分区主要是用来保护数据在预先确定数目的分区中平均分布。他可以在基于用户定义的表达式的返回值来进行选择分区,该表达式使用将要插入到表中的这些行的列值进行计算 例4:把不同时期的入职时间进行hash >Partition by hash(year(hired)) >partitions 4 >; 例5、 可以查看到数库分为5个分区,从0到4,在加上frm文件和par文件,供12个文件。 4.4.4range分区技术 不同分区技术对比 创建索引,也是一种提高数据库效率的方法。 Mysql>Create index idx_id on t2(id); Mysql>show index from t2; 测试1:大数据测试 首先建立一个表,插入几个数据进行测试,然后使用select into t2 select * fromt2;进行倍数的增加 再打开一个终端,发现是均匀分配数据的。还有一个发现,有时索引比数据更大,造成空间浪费。 插入1000万行记录,然后看时间和大小,1000万条记录。 查看数据库文件大小 实验二、用存储过程生成大数据 存储过程:是一种通过创建语句,然后调用数据库的方法。 通过存储过程灌入800万条测试数据库 Mysql>delimiter // Mysql>create procedure load_part_tab() Begin Declare v <8000000 Do Insert into part_tab Values (v,’testing partitions’,adddate(‘2000-01-01’,(rand(v)*36520)mod 3652)); Set v=v+1; End while; End // Mysql>delimiter; 分别插入数值和字段“testingpartition“和随机时间。 Mysql>? procedure//查看存储帮助 再创建一个两个表,一个使用分区实例,一个不使用分区实例,然后调用存储过程即可完成内容的插入,最后测试。 Mysql分区实例: Mysql>create table part_tab (c1 int default null,c2 varchar(30) default null, c3 date default null ) engine=myisam Partition by range(year(c3))( Partition p0 values less than(2000), Partition p1values less than(2001), Partition p2 values less than(2002), Partition p3 values less than(2003), Partition p4 values less than(2004), Partition p5 values less than(2005), Partition p6 values less than(2006), Partition p7 values less than(2006), Partition p8 values less than(2007), Partition p9 values less than(2008), Partition p10 vlues less than maxvalue); 创建未分区实例: Mysql> create table no_part_tab (c1 int default null,c2 varchar(30) default null, c3 date default null ) engine=myisam; 利用存储过程插入数据: Mysql>call load_part_tab(); Mysql>inset into no_part_tab select * from part_tab; 测试:SQL性能 Mysql>select count(*) from part_tab where c3>date ‘2000-01-01’ and c3<’2000-12-31’;//大约0.55秒 Mysql> select count(*) from no_part_tab where c3>date ‘2000-01-01’ and c3<’2000-12-31’;//大约5秒 相差10倍,说明分区技术可以有效降低查询时间。 检索范围查看到,分区表查找范围明显很小为79万。 如果创建索引再查看结果: Mysql>create index_c3 on no_part_tab(c3); Mysql> create index_c3 on part_tab(c3); 测试: 发现创建索引之后测试访问时间发现明显二者都显著变小,说明索引也是一种优化查询的方法。下图是查找未索引的字段。 4.5innodb表创建分区表 Innodb是一种事务型的表存储引擎。对于innodb表,要区分两个概念。共享表空间和独占表空间。 共享表空间:某个数据库的所有表的数据,存储在一个数据文件中,默认的文件名为ibdata1,初始化为10MB。 独占表空间:每一个表都将会生成独立的文件来存储数据,每一个表除了一个frm文件还有一个.ibd文件。 只有把innodb设置成独立表空间以后,才能创建innodb的表分区。 Vi /etc/my.cnf//将innodb_file_per_table =1,重启mysql即可 然后创建表,指定引擎和分区情况,查看数据文件即可看到分区文件顺利生成。 本文转自zsaisai 51CTO博客,原文链接:http://blog.51cto.com/3402313/966578

优秀的个人博客,低调大师

服务器架构之性能扩展-第六章(7)

第六章 nagios网络监控和shell邮件报警 对于nagios比较感兴趣的朋友,对于nagios警报的部分可以参考我的网络监控漫谈系列。 6.1网络管理概念 网络管理:监督、组织和控制网络通信服务和信息处理所必须的各种活动的总称。 常见的监控设备有交换机、路由器,windows或linux主机,它一般包含监控端和被监控端,监控端定时检测叫轮训,被监控端的紧急情况的主动报告叫中断。 监控协议:SNMP(simple network manager protocol) 6.1.1windows部署snmp 开始-》控制面板-》添加删除windows组件-》管理和监视工具-》详细信息-》简单网络管理协议 6.2postfix邮件报警 6.2.1postfix的部署 Postfix是一款比sendmail速度更快的邮件服务器,我们这里选择centos服务器上搭建postfix和dovecat邮件服务,然后通过windows8的outlook进行访问。 1. 关闭 sendmail 邮件服务 Service sendmail stop Chkconfig sendmail off 2. 安装 postfix Postfix是发送服务,使用25端口,dovecat完成邮件的接收,使用110端口,共同完成邮件的收发。 Yum install postfix* Yum install dovecat* 3. 修改配置文件 Vi /etc/postfix/main.cf Myhostname指定邮件主机域名 Mydomain指定邮件域名后缀 Myorigin指定发件人后缀 Inet_interface指定all,注释localhost,这样允许所有客户端的使用 Mydestination指定目标主机 myNetworks指定服务器的网段 Relay_domains允许中继转发 Service postfix restart Chkconfig postfix on Vi /etc/dovecot.conf 取消protocal的注释,开启110端口 4. 更改默认邮件服务器 Alternative –config mta然后选择2,即postfix 5 、新建账户 即可使用user1@saisai.com和user2@saisai.com邮箱 Vi /etc/hosts//解析域名 2. 测试 首先服务器和客户机可以ping通 打开outlook-》工具-》创建用户 输入账户信息,本地测试,选择”手动配置服务器或其他服务器类型”,输入服务器ip和用户名和密码即可。设置完毕,然后单击“测试账户设置”进行测试。 然后通过发送/接收选项,进行选择账户,然后进行“新建”,进行邮件发送测试。 选择账户2,进行查看是否可以接收邮件 命令方式测试: telnet 192.168.211.128 25 Telnet发邮件,ip+端口,然后写mail from:设置发送方,rcpt to:设置接收方,data:写数据,以点结束邮件内容,以quit退出。 登陆用户查看邮件 回复邮件,回复给root用户 Root用户邮件,用Mail 命令查看,输入id号查看内容 Mail命令发送邮件 Echo为内容,-s为主机,mail后接邮箱 实验一:测试test.sh脚本 建立一个sh命令,然后赋予写的权限,执行即可。 主题test shell,内容shell test 执行之后,到邮箱进行查看 实验二:apache服务脚本Apache.sh Nc -w2 localhost 80 该命令执行成功后两秒自动退出,然后使用$?判断端口是否开放,如果上条命令成功则结果为0,否则为1。 于是通过检测80端口是否正常,不正常则重启apache 到邮箱进行检测 实验三:mysql数据库脚本mysql.sh 通过检测3306端口,如果不正常则重启mysql 到邮箱进行检测 实验四:磁盘检测disk.sh 通过awk来检测磁盘使用情况,awk ‘NR==3{print $4}’它可以抠取第三行第四列的值,然后利用它来判断磁盘的大小。 用dd命令,增加一个大文件,进行测试 打开邮件进行验证 实验五:建立Crontab计划任务 Crontab –e 本文转自zsaisai 51CTO博客,原文链接:http://blog.51cto.com/3402313/967782

优秀的个人博客,低调大师

服务器架构之性能扩展-第十二章(13)

十二章、LAMP环境搭建的自动化搭建 所谓自动化搭建当然是实现一定的自动化部署了,并且可以承受一定的大型的网站点击量,LAMP环境的部署完全可以使用自动化脚本实现,这样便达到了无人值守的安装方式。 1、准备下列软件 httpd-2.2.14.tar.gz mysql-5.1.41.tar.gz gd-2.0.35.tar.gz php-5.2.11.tar.gz freetype-2.3.10.tar.gz jpegsrc.v7.tar.gz libpng-1.2.41.tar.gz 下载好,上传到/root/apmg_install. 2、编写一个安装指南install放在/root/apmg_install 下载后,tar zxvf apmg_install.tar.gz ; cd apmg_install; ./setup.sh自动完成安装,时间大概10多分钟 3、编写httpd.sed文件放在/root/apmg_install 目的是为了在apache的httpd.conf中加入相关的行。 文件httpd.sed内容:/application\/x-compress .Z/a\ \ AddType application/x-httpd-php .php 4、编写test.php放在/root/apmg_install <?php phpinfo(); ?> 5、编写测试脚本放在/root/apmg_install/setup.sh 这个脚本基于linux和freebsd,可能要经过多次测试才成功。 #!/bin/sh #this is a script about *nix installing apache,php with gd2.write by sery(sery@163.com),in 2009-12-03 #define some variables http_prefix=/usr/local/apache2 php_prefix=/usr/local/php #need root install is_root=`id |awk ‘{print $1}’|awk -F’[=(]‘ ‘{print $2}’` if [ $is_root != 0 ] then echo“please use root install this program!!!” exit 1 fi #Os is ? Os_is=`uname` if [ "$Os_is" = "FreeBSD" ] then ## install apache if [ ! -d "$http_prefix" ] then tar zxvf httpd-2.2.14.tar.gz cd httpd-2.2.14 ./configure --prefix=$http_prefix --enable-so --enable-write --with-mpm=worker make make install cd .. if [ ! -f "$http_prefix/htdocs/test.php" ] then cp test.php $http_prefix/htdocs fi rm -rf httpd-2.2.14 echo“apache install is ok!” sleep 2 fi #install mysql client is_inst_mysql=`find /usr/local/bin -name mysql | wc -l` if [ "$is_inst_mysql" = 0 ] then tar zxvf mysql-5.0.41.tar.gz cd mysql-5.0.41 ./configure --without-server --with-extra-charsets=gbk,gb2312,utf8 --enable-thread-safe-client make make install cd .. echo“/usr/local/lib”>>/etc/ld.so.conf ldconfig rm -rf mysql-5.0.41 echo“mysql client install ok!” sleep 2 fi #install gd2 if [ ! -d /usr/local/gd2 ] then tar zxvf gd-2.0.35.tar.gz cd gd-2.0.35 ./configure --prefix=/usr/local/gd2 make make install cd .. rm -rf gd-2.0.35 echo“gd2 install is ok!” sleep 2 fi #install php.apache must be installed in /usr/local/apache2 if [ ! -d /usr/local/php ] then tar zxvf php-5.3.6.tar.gz cd php-5.3.6 ./configure --prefix=$php_prefix --with-gd=/usr/local/gd2 --with-apxs2=$http_prefix/bin/apxs --enable-mbregex --enable-bcmath --with-mysql --with-zlib-dir --enable-mbstring=all --with-freetype-dir --with-pdo-mysql make make install cp php.ini-dist $php_prefix/lib/php.ini cd .. rm -rf php-5.3.6 echo“php with gd2 install is ok!” sleep 2 fi # setting apache configuration file sed -f httpd.sed $http_prefix/conf/httpd.conf>$http_prefix/conf/httpd.conf.temp cd $http_prefix/conf mv httpd.conf httpd.conf.old cat httpd.conf.temp>httpd.conf $http_prefix/bin/apachectl -t cd echo“It is very ok!” elif [ "$Os_is" = "Linux" ] then echo“this linux” ## install apache if [ ! -d "$http_prefix" ] then tar zxvf httpd-2.2.14.tar.gz cd httpd-2.2.14 ./configure --prefix=$http_prefix --enable-so–enable-write --with-mpm=worker make make install cd .. if [ ! -f "$http_prefix/htdocs/test.php" ] then cp test.php $http_prefix/htdocs fi rm -rf httpd-2.2.14 echo“apache install is ok!” sleep 2 fi #install mysql client is_inst_mysql=`find /usr/local/bin -name mysql | wc -l` if [ "$is_inst_mysql" = 0 ] then tar zxvf mysql-5.0.41.tar.gz cd mysql-5.0.41 ./configure --without-server --with-extra-charsets=gbk,gb2312,utf8 --enable-thread-safe-client make make install cd .. echo“/usr/local/lib”>>/etc/ld.so.conf ldconfig rm -rf mysql-5.0.41 echo“mysql client install ok!” sleep 2 fi #install freetype if [ ! -d /usr/local/freetype ] then tar zxvf freetype-2.3.5.tar.gz cd freetype-2.3.5 ./configure --prefix=/usr/local/freetype make make install cd .. rm -rf freetype-2.3.5 echo“freetype install is ok!” sleep 2 fi #install jpeg if [ ! -d /usr/local/jpeg ] then tar zxvf jpegsrc.v6.tar.gz cd jpeg-6 ./configure --prefix=/usr/local/jpeg make make install cd .. rm -rf jpeg-6 echo“gpeg install is ok!” fi #install libpng if [ ! -d /usr/local/libpng ] then tar zxvf libpng-1.2.31.tar.gz cd libpng-1.2.31 ./configure --prefix=/usr/local/libpng make make install cd .. rm -rf libpng-1.2.31 echo“libpng install is ok!” sleep 5 fi #link header file if [ ! -f /usr/include/pngconf.h ] then ln -s /usr/local/libpng/include/pngconf.h /usr/include fi if [ ! -f /usr/include/png.h ] then ln -s /usr/local/libpng/include/png.h /usr/include fi #install gd2 if [ ! -d /usr/local/gd2 ] then tar zxvf gd-2.0.35.tar.gz cd gd-2.0.35 ./configure --prefix=/usr/local/gd2 --with-freetype=/usr/local/freetype --with-png=/usr/local/libpng --with-jpeg=/usr/local/ jpeg make make install cd .. rm -rf gd-2.0.35 echo“gd2 install is ok!” sleep 2 fi #install php.apache must be installed in /usr/local/apache2 if [ ! -d /usr/local/php ] then tar zxvf php-5.3.6.tar.gz cd php-5.3.6 ./configure --prefix=$php_prefix --with-gd=/usr/local/gd2 --with-apxs2=$http_prefix/bin/apxs --enable-mbregex --enable-bcmath --with-mysql --with-zlib-dir --enable-mbstring=all --with-pdo-mysql --with-freetype=/usr/local/freetype make make install cp php.ini-dist $php_prefix/lib/php.ini cd .. rm -rf php-5.3.6 echo“php with gd2 install is ok!” sleep 2 fi # setting apache configuration file sed -f httpd.sed $http_prefix/conf/httpd.conf>$http_prefix/conf/httpd.conf.temp cd $http_prefix/conf mv httpd.conf httpd.conf.old cat httpd.conf.temp>httpd.conf $http_prefix/bin/apachectl -t cd echo“It is very ok!” else echo“this is other os,please modify the script” exit 1 fi 6、以上准备工作做好以后,执行setup.sh 执行完毕后,启动apache,然后运行test.php测试 然后执行,setup权限不够赋予权限。 遇到下面的错误提示,如果sh目录存在且脚本无误,最可能是原因是在windows下写的脚本是dos格式的,放在Linux下编码不识别,解决方法是使用dos2unix命令转一下,即输入:dos2unix文件名 我们可以看到,飞快的执行程序呢?结果我们拭目以待。 还有一点特别提醒,我们编写脚本文件的时候是在window条件下,虽然执行了转换,但难免会有乱码,所以一定要vi setup.sh文件查看,还要留心标点符号也要符合linux环境才行。如windows下的‘’“”要转换为linux下的' '和" "。 编译遇到了php5模块没加载正确。查文档需要关闭selinux。 Vi /etc/sysconfig/selinux 把SELINUX=enforcing注释掉:#SELINUX=enforcing,然后新加一行为: SELINUX=disabled然后重启从新编译。 我们然后在编译这次出现 几乎都是ok啦,我们执行/usr/local/apache2/bin/apachectl start 编译完毕我们测试一下:http://192.168.22.132/test.php 7、打包归档 cd /root切换到root tar zcvf apmg_install.tar.gz apmg_install 这样将打包好保存起来,下次可以解包直接使用 本文转自zsaisai 51CTO博客,原文链接:http://blog.51cto.com/3402313/1036233

优秀的个人博客,低调大师

ARM要将服务器扩展到物联网领域

ARM在11月10日(星期二)召开的年会上审视了公司从服务器到物联网云服务过渡的各项工作。ARM公司技术总监Mike Muller在开幕式上做主题演讲时对半导体行业的未来表示乐观。 Muller 表示,“有些人说摩尔定律已经趋向平坦,但我仍然认为前方有大量令人难以置信的创新。” 为了强调他的观点,他在印刷电路板上展示了六英寸硅片的等价物。Muller表示,此款2微米NMOS设计“不是非常强大,但它开辟了一个全新的计算世界”。他称,“这东西将永远滞后硅20年,但它可以开拓新的应用,尺寸并不是一定要越来越小, 10万个晶体管已经可以做许多事情了。” 作为前方创新的例子,Muller展示一塑料膜上的硅片 Muller还描述了一款高端、基于ARM的服务器和SoC,几家公司已经在销售这些产品。ARM自己的网站现在是在惠普基于ARM的服务器上运行。ARM在今年早些时候宣布,AMR认为 AMR可以获取服务器处理器市场25%的份额,并称到2020年可获取用于通信设备的嵌入式处理器45%的份额。 另一方面,Muller还宣布了新的连接物联网和云的服务。该款Mbed设备服务器在网上已经有售,开发人员可以免费使用,但连接限于100台设备及事件处理低于10,000次/小时。 ARM还宣布了一项利用智能手机进行身份验证和安全部署消费者物联网设备的网络服务。明年,ARM计划提供更多用于部署和管理物联网设备网络服务。 Muller表示,新服务的目标之一是“令物联网像个移动网络,而不是像嵌入式控制”,这对于数以百万计的应用程序开发人员来说意义重大,因为“他们是推动大多数未来创新的一群人”。 ARM去年推出了自己的物联网节点操作系统Mbed。ARM 物联网项目经理Christian Flautner,表示,“操作系统需要与各种标准和安全性共存,我们在操作系统生态圈里看到一大块空白。为了简化这些设备的构建,我们做了多年的努力。” Muller表示,去年ARM在自己的主流市场获取了移动处理器插座市场85%的份额,到明年,ARM将获取对应的64位系统市场份额的一半以上。尽管移动设备增长速度下降到了10%左右,ARM预计到2020年移动设备将达28亿件,其中10亿是低端手机。 Muller在主题演讲中宣布了一款新的入门级智能手机处理器以及一个用于32位ARM微控制器的安全系统。 ARM没有提供代号为Artemis的下一代高端移动处理器的细节。但ARM的CPU集团总经理James McNiven表示,ARM计划继续强化自己的Big.little(大.小)法,将大核和小核混合起来。 原文发布时间为:2015年11月11日 本文来自云栖社区合作伙伴至顶网,了解相关信息可以关注至顶网。e

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册