对多线程刚入手,请教达人!
有一程序中有大耗时计算任务,在主线程中计算估计耗时数十小时。
有一8核服务器,打算利用其多核特点,开多线程,提高效率,但是没有明显改善。
在任务分解上没有问题。开了两个专用于计算的线程,但是发现cpu占用率还没有使用没有使用单线程的时候高。
我知道开多线程不会是两个线程就是原来的一半,三个就是原来的三分之一的关系,但是耗费的时间和原单线程相差无几。
大家能否帮助我分析一下原因。对了开的用于计算的线程优先级订到了最高。
开的线程是并行的。不涉及资源问题。各自使用自己资源。没有锁的问题
开始线程之前,建了两个同一个类的对象,然后再开两个线程,运行的分别是两个对象的同一个方法.他们之间不涉及资源问题。
两个线程对同一个数据库同一张表作不同的查询,返回结果,各个线程处理自己的查询的结果。
关键代码如下:
在public partial class Form1 : Form
{
。
private void button2_Click(object sender, EventArgs e)
{
// 这是两个用于计算的对象。
DealData MyDeal = new DealData(iFace.NetName, iFace.TimeSpanType);
DealData MyDeal1 = new DealData(iFace.NetName, iFace.TimeSpanType); MyDeal.MyData = new OutPutData(iFace.NodeNum, iFace.SectionNum, 1);
MyDeal1.MyData = new OutPutData(iFace.NodeNum, iFace.SectionNum, 1);
//用于计算的参数,在Deal中使用。
MyDeal.Time1 = new DateTime(2008, 1, 1);
MyDeal.Time2 = new DateTime(2008, 7, 1);
MyDeal1.Time1 = new DateTime(2008, 7, 1);
MyDeal1.Time2 = new DateTime(2009, 1, 1);
//开两个线程
System.Threading.Thread newThread;
newThread = new System.Threading.Thread(MyDeal.Deal);
System.Threading.Thread newThread1;
newThread1 = new System.Threading.Thread(MyDeal1.Deal);
newThread.Priority = ThreadPriority.Highest;
newThread1.Priority = ThreadPriority.Highest;
newThread.Start();
newThread1.Start();
}
class DealData
{ //用于放参数
public DateTime Time1,Time2;
public void Deal()
{
//ConString是已知的
SqlConnection connection = new SqlConnection(ConString);
SqlCommand command = new SqlCommand("FindinTimeGap", connection);
command.CommandType = CommandType.StoredProcedure;
SqlParameter parameter1 = command.Parameters.Add("@timeentry", SqlDbType.DateTime);
SqlParameter parameter2 = command.Parameters.Add("@timeexit", SqlDbType.DateTime);
connection.Open();
parameter1.Value = Time1;
parameter2.Value = Time2;
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
try
{
长耗时计算部分
}
catch
{
。
};
};
reader.Close();
connection.Close();
}
有一程序中有大耗时计算任务,在主线程中计算估计耗时数十小时。
有一8核服务器,打算利用其多核特点,开多线程,提高效率,但是没有明显改善。
在任务分解上没有问题。开了两个专用于计算的线程,但是发现cpu占用率还没有使用没有使用单线程的时候高。
我知道开多线程不会是两个线程就是原来的一半,三个就是原来的三分之一的关系,但是耗费的时间和原单线程相差无几。
大家能否帮助我分析一下原因。对了开的用于计算的线程优先级订到了最高。
开的线程是并行的。不涉及资源问题。各自使用自己资源。没有锁的问题
开始线程之前,建了两个同一个类的对象,然后再开两个线程,运行的分别是两个对象的同一个方法.他们之间不涉及资源问题。
两个线程对同一个数据库同一张表作不同的查询,返回结果,各个线程处理自己的查询的结果。
关键代码如下:
在public partial class Form1 : Form
{
。
private void button2_Click(object sender, EventArgs e)
{
// 这是两个用于计算的对象。
DealData MyDeal = new DealData(iFace.NetName, iFace.TimeSpanType);
DealData MyDeal1 = new DealData(iFace.NetName, iFace.TimeSpanType); MyDeal.MyData = new OutPutData(iFace.NodeNum, iFace.SectionNum, 1);
MyDeal1.MyData = new OutPutData(iFace.NodeNum, iFace.SectionNum, 1);
//用于计算的参数,在Deal中使用。
MyDeal.Time1 = new DateTime(2008, 1, 1);
MyDeal.Time2 = new DateTime(2008, 7, 1);
MyDeal1.Time1 = new DateTime(2008, 7, 1);
MyDeal1.Time2 = new DateTime(2009, 1, 1);
//开两个线程
System.Threading.Thread newThread;
newThread = new System.Threading.Thread(MyDeal.Deal);
System.Threading.Thread newThread1;
newThread1 = new System.Threading.Thread(MyDeal1.Deal);
newThread.Priority = ThreadPriority.Highest;
newThread1.Priority = ThreadPriority.Highest;
newThread.Start();
newThread1.Start();
}
class DealData
{ //用于放参数
public DateTime Time1,Time2;
public void Deal()
{
//ConString是已知的
SqlConnection connection = new SqlConnection(ConString);
SqlCommand command = new SqlCommand("FindinTimeGap", connection);
command.CommandType = CommandType.StoredProcedure;
SqlParameter parameter1 = command.Parameters.Add("@timeentry", SqlDbType.DateTime);
SqlParameter parameter2 = command.Parameters.Add("@timeexit", SqlDbType.DateTime);
connection.Open();
parameter1.Value = Time1;
parameter2.Value = Time2;
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
try
{
长耗时计算部分
}
catch
{
。
};
};
reader.Close();
connection.Close();
}
解决方案 »
- JavaScript调用CS后台的Click的事件
- 发布程序的问题
- 我要获取一个列表框中所有的项目,填入另一个列表框,请问下面的代表怎么改啊
- 求解
- 分发器求助
- 一个怪异的问题,发在这里,因为人气旺……
- C# WinForm 数据库 主从表问题( SqlConnection,SqlDataAdapter,DataSet,SqlCommandBuilder)
- CS0118: “System.Xml.Schema.ValidationEventHandler”是“类型”,但此处被当做“变量”来使用
- 右键关联菜单?
- 小问题两个
- 实在不明白 为什么JAVA NET 需要虚拟机
- Response.Write("<script>window.open();</script>");不传值?
跟操作系统也有关系的。
服务器的话,还是安装2003比较好吧,XP感觉还是不够~~~
你先多开几个线程试试不就有结果了?最近我也在搞系统性能的问题,也是8核cpu,压力一上来,就90%几了。线程绝不是越多越好,少了也没效率。
DataView dataCollection = null;void MainThread()
{
int selectStartIndex = 0;//有顺序字段的起始值
while(true)
{
dataCollection = GetData(conditon);//condition 为 select top 1500 * from table where key > selectStartIndex
if(dataCollection.Count <= 0)
{
break;
}
perThreadProcessCount = Math.Round(dataCollection.Count / events.Length,0);Thread[] thds = new Thread[events.Length];
int perStartIndex = 0;
for(int i = 0;i < thds.Length;i ++)
{
perStartIndex = perThreadProcessCount * i;
events[i] = new AutoResetEvent(false);
thds[i] = new Thread(delegate(){
if(perStartIndex < dataCollection.Count)
{
for(int j = perStartIndex; j < perThreadProcessCount; j ++)
{
if(j < dataCollection.Count)
{
DataRowView drv = dataCollection[i];
//处理数据
}
}
}
events[i].Set();
}
AutoResetEvent.WaitAll(events);
selectStartIndex = Convert.ToInter32(dataCollection[dataCollection.Count -1][key]);
}}大致就是这样了,因为手写的,可能有些语法或者括号位置不对,应该能读懂吧。
再请教。
会再单核中执行,
sdp081218,老兄,您这么说是为什么?
一般同一进程中的线程系统会优先考虑它们的亲缘性而尽量安排在同一个核心上运行,虽然你开了多线程,但是线程如果
并不是总在忙的话,线程之间很可能都在同一个核心上被调度的。楼主要把真正的时间密集运算部分分离出来,调整一下
任务分配。如果 while (reader.Read()) 的运行频率很高并且reader.Read() 是阻塞的,那么线程进入睡眠的时间就会很多,
建议楼主考虑将reader.Read() 作为单独的任务与计算任务分离开来。可以开很多的reader.Read()线程,但是运算
线程的数目只需和核心数目差不多应该就可以了,所有的reader.Read()线程的结果都提交给运算线程做运算
一般同一进程中的线程系统会优先考虑它们的亲缘性而尽量安排在同一个核心上运行,虽然你开了多线程,但是线程如果
并不是总在忙的话,线程之间很可能都在同一个核心上被调度的。
这些知识在哪有介绍?MSDN?