关于并发下内存及CPU使用情况的思考
鉴于昨天的文章<<使用Interlocked在多线程下进行原子操作,无锁无阻塞的实现线程运行状态判断>>里面有一个封装好的无锁的类库可以判断并发下的结束状况,我们可以完成并发时,以及并发的同时做一些事,因此,今天我做了个小demo:
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleApp6
{ public enum CoordinationStatus
{
AllDone,
Timeout,
Cancel
}; public sealed class AsyncCoordinator
{
private Int32 m_opCount = ; // Decremented when AllBegun calls JustEnded
private Int32 m_statusReported = ; // 0=false, 1=true
private Action<CoordinationStatus> m_callback;
private Timer m_timer; // This method MUST be called BEFORE initiating an operation
public void AboutToBegin(Int32 opsToAdd = )
{
Interlocked.Add(ref m_opCount, opsToAdd);
} // This method MUST be called AFTER an operations result has been processed
public void JustEnded()
{
if (Interlocked.Decrement(ref m_opCount) == )
ReportStatus(CoordinationStatus.AllDone);
} // This method MUST be called AFTER initiating ALL operations
public void AllBegun(Action<CoordinationStatus> callback, Int32 timeout = Timeout.Infinite)
{
m_callback = callback;
// 是否需要永远运行
if (timeout != Timeout.Infinite)
{
// 在指定的时间点(dueTime) 调用回调函数,随后在指定的时间间隔(period)调用回调函数
m_timer = new Timer(TimeExpired, null, timeout, Timeout.Infinite);
}
JustEnded();
} // 处理过时的线程
private void TimeExpired(Object o)
{
ReportStatus(CoordinationStatus.Timeout);
} public void Cancel()
{
if (m_callback == null)
throw new InvalidOperationException("Cancel cannot be called before AllBegun");
ReportStatus(CoordinationStatus.Cancel);
} private void ReportStatus(CoordinationStatus status)
{
if (m_timer != null)
{ // If timer is still in play, kill it
Timer timer = Interlocked.Exchange(ref m_timer, null);
if (timer != null) timer.Dispose();
} // If status has never been reported, report it; else ignore it
if (Interlocked.Exchange(ref m_statusReported, ) == )
m_callback(status);
}
} class Program
{
static AsyncCoordinator m_ac = new AsyncCoordinator();
static void Main(string[] args)
{
Console.BufferHeight = Int16.MaxValue - ;
Console.BufferWidth = Int16.MaxValue - ; ConcurrentQueue<int> concurrentQueue = new ConcurrentQueue<int>(); for(int i =;i<; i++)
{
concurrentQueue.Enqueue(i);
} Console.WriteLine("添加完毕...."); var t = new Task[]; for (int i=; i<; i++)
{
m_ac.AboutToBegin();
t[i] = Task.Factory.StartNew((param) =>
{
while (concurrentQueue.Count>)
{
int x;
if(concurrentQueue.TryDequeue(out x))
{
Console.WriteLine(x + " 线程Id: {0}, 线程数: {1}", Task.CurrentId, param.ToString());
}
//Thread.Sleep(150);
}
m_ac.JustEnded();
}, i);
} m_ac.AllBegun(AllDone, Timeout.Infinite);
Console.ReadKey();
} public static void AllDone(CoordinationStatus status)
{
switch (status)
{
case CoordinationStatus.Cancel:
Console.WriteLine("Operation canceled.");
break; case CoordinationStatus.Timeout:
Console.WriteLine("Operation timed-out.");
break; case CoordinationStatus.AllDone:
Console.WriteLine("处理完毕....");
break;
}
}
}
}
但是发现了一个问题:
这CPU使用率....
然后我看了下输出结果:
可以看到线程数才只有5个(我的线程数是从0开始算的),这不会啊,明明我们就开了50个线程啊,不过不管开多少个线程,这CPU扛不住啊,要是说在项目中的某个模块需要用到并发,这CPU使用率你扛得住?服务器本来配置就不会太好,网站的其余模块不要用CPU了?而且,我明明开了50个线程跑啊,为什么只有五个线程?其实很简单,因此并发下,代码只用了五个线程就跑完了这一万个数据,剩下的线程开了没有用武之地。找到只有五个线程开着的原因了之后,要想想怎么解决啊,多的45个线程也是要占内存的,尽管是线程池线程,但也是要占用内存啊,既然是因为并发下运行太快,只要五个线程就能跑满一万个数据,那我就阻塞一会线程就可以了,这样让剩下的45个线程能够有机会运行。改代码!
将上面的Thread.Sleep(150)的注释给去掉哦!

嗯,这个结果还是可以的,但是有个Console host占用内存高啊,占就占呗,反正该用的内存还是要用。我们睡眠了一段时间的线程,那么与不睡眠相比,并发的CPU使用率是不是下降了?我们开线程最好的期待不就是跑满CPU么?其实不然,开线程不过就是为了更快的运行程序,将耗时的程序分批次运行,但是如果期间占用CPU太高,我这里是个demo,占用CPU时间很短,也就几十秒。但是真的项目中会允许么?具体情况具体分析吧,如果不介意的话,可以这么跑,大不了另外弄个服务器专门跑并发,然后将数据存储到数据库中(如果你的业务是: 并发调用第三方接口,然后将接口获取的数据做处理,完全可以采用这种设计)。但是请注意,还是不要太耗费CPU的好。
并发线程的睡眠时间,我们也可以自己调节下,建议是100-200ms吧。
关于并发下内存及CPU使用情况的思考的更多相关文章
- centos文件/文件夹操作-检查磁盘、内存、cpu使用情况-vi操作命令
Part1:CentOS文件/文件夹操作 1.新建文件夹 即创建目录 mkdir 文件名 新建一个名为test的文件夹在home下 vi source1 mkdir /home/test 注意:当创建 ...
- adb命令检测apk启动时间、内存、CPU使用情况、流量、电池电量等——常用的adb命令
ADB:Android Debug Bridge,是Android SDK里一个可以直接操作安卓模拟器或真实设备的工具,颇为强大. 检测APP: adb shell am start -W p ...
- Linux中内存、CPU使用情况查看
1.背景 在实际生产中我们为了保证系统能稳定运行,我们经常要查看当前的CPU和系统使用情况 建议使用top,简单丰富,快捷 2.使用free查看内存使用情况 3.使用 top查看内存.cpu内存占比 ...
- 【linux】查看内存和CPU使用情况
1.内存命令:free 解释:以上数据单位KB. 所以,上面的mem物理内存共1G 下面是对这些数值的解释: total:总计物理内存的大小. used:已使用多大. free:可用有多少. Shar ...
- [转载]查看基于Android 系统单个进程内存、CPU使用情况的几种方法
转载自: http://www.linuxidc.com/Linux/2011-11/47587.htm 一.利用Android API函数查看1.1 ActivityManager查看可用内存. A ...
- 查询进程内存,cpu占用情况。僵尸进程
查使用内存最多的5个进程:ps aux | head -1 && ps aux | grep -v USER | sort -nr -k 4 | head -5 查使用CPU最多的5个 ...
- linux下面实时查看进程,内存以及cpu使用情况使用命令
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器 可以直接使用top命令查看整体情况,如图: 但是这样虽然看的东西多,但是闲的比较 ...
- ubuntu查看内存占用和查看cpu使用情况的简单方法(ubuntu内存管理)
单独查看内存使用情况的命令:free -m查看内存及cpu使用情况的命令:top也可以安装htop工具,这样更直观,安装命令如下:sudo apt-get install htop安装完后,直接输入命 ...
- Ubuntu——查看内存和CPU情况
查看内存及cpu使用情况的命令:top 也可以安装htop工具,这样更直观,安装命令如下:sudo apt-get install htop安装完后,直接输入命令:htop
随机推荐
- Android初级教程:对文件和字符串进行MD5加密工具类
转载请注明出处:http://blog.csdn.net/qq_32059827/article/details/52200008 点击打开链接 之前写过一篇博文,是针对字符串进行md5加密的.今 ...
- Java并发框架——AQS阻塞队列管理(三)——CLH锁改造
在CLH锁核心思想的影响下,Java并发包的基础框架AQS以CLH锁作为基础而设计,其中主要是考虑到CLH锁更容易实现取消与超时功能.比起原来的CLH锁已经做了很大的改造,主要从两方面进行了改造:节点 ...
- java异常体系结构详解
前几天在参加网易和360公司的在线考试的时候,都出了一道关于java中异常类的多项选择题.这几天翻看了相关书籍和网上一些资料,结合自己的理解与思考,将自己的一些收获记录如下: 先来看看java中异常的 ...
- 纯CSS箭头,气泡
原文地址: CSS Triangles 演示地址:CSS Triangles Demo 原文日期: 2013年8月5日 翻译日期: 2013年8月9日 本文两种实现方式: 使用或不使用 before ...
- UNIX环境高级编程——sigqueue、sigsuspend函数
一.sigqueue函数 功能:新的发送信号系统调用,主要是针对实时信号提出的支持信号带有参数,与函数sigaction()配合使用. int sigqueue(pid_t pid, int sig, ...
- JAVA之旅(十六)——String类,String常用方法,获取,判断,转换,替换,切割,子串,大小写转换,去除空格,比较
JAVA之旅(十六)--String类,String常用方法,获取,判断,转换,替换,切割,子串,大小写转换,去除空格,比较 过节耽误了几天,我们继续JAVA之旅 一.String概述 String时 ...
- HTML5 预加载
原文地址: HTML5 Link Prefetching 原文日期: 2010年07月07日 翻译日期: 2013年08月13日 浏览器厂商和开发者之间共同努力的一个方向就是让网站更快.现在已有很多广 ...
- JAVA之旅(十一)——RuntimeException,异常的总结,Package,jar包,多线程概述
JAVA之旅(十一)--RuntimeException,异常的总结,Package,jar包,多程序概述 继续JAVA之旅 一.RuntimeException 在Exception种有一个特殊的子 ...
- java的制作"时间账本"
一直以来我都感觉自己的时间过得好荒废啊,貌似只是打开了一个网页链接的时间,一个下午便过去了:仿佛就是看了看空间,刷了刷微信,一天就过去了.哈,当然这是夸张的说法.但是我仔细地算了一下,大概我们每个人每 ...
- XBMC源代码简析 5:视频播放器(dvdplayer)-解复用器(以ffmpeg为例)
XBMC分析系列文章: XBMC源代码分析 1:整体结构以及编译方法 XBMC源代码分析 2:Addons(皮肤Skin) XBMC源代码分析 3:核心部分(core)-综述 XBMC源代码分析 4: ...