线程问题

sunny906 2011-09-20 12:04:58
有10个txt文件,每个文件都需要1秒钟更新一次

多线程并发访问数据库,并生成txt文件,线程都是1秒钟执行一次,执行方法如下:
线程1------->访问数据库表1------->生成1.txt文件,如果文件存在,则重写
线程2------->访问数据库表2------->生成2.txt文件,如果文件存在,则重写
... ...

线程9------->访问数据库表9------->生成9.txt文件,如果文件存在,则重写
线程10------->访问数据库表10------->生成10.txt文件,如果文件存在,则重写


单线程,依次访问数据库,并生成txt文件,线程也是1秒钟执行一次,执行方法如下:
线程------->访问数据库表1------->生成1.txt文件,如果文件存在,则重写
------->访问数据库表1------->生成1.txt文件,如果文件存在,则重写
------->访问数据库表2------->生成2.txt文件,如果文件存在,则重写
... ...

------->访问数据库表10------->生成10.txt文件,如果文件存在,则重写

现在的问题是:
如果采用多线程的话,就会出现多个文件长时间没有被重写(即更新);并且多线程并发访问数据库,会导致程序性能降低。
如果采用单线程的话,文件虽然都能更新到,但达不到即时更新(也就是1秒更新一次)的效果。

请教各位达达,遇到这种情况该如何做才能更优?
...全文
308 40 打赏 收藏 转发到动态 举报
写回复
用AI写文章
40 条回复
切换为时间正序
请发表友善的回复…
发表回复
myceolzy 2011-09-23
  • 打赏
  • 举报
回复
应当优化你数据库访问的方法。
我猜想你是否所有的线程是采用的一个静态方法来访问数据库,这样你如果一个线没有结束访问,就会造成其它线程无法访问;
你可以每一个线程访问访问数据库的时候 都NEW一个新方法出来,并要及时的关闭他,SQL方面他自己会处理了连接池这些,你不用担心数据库打开关闭等这些性能问题!
sunny906 2011-09-23
  • 打赏
  • 举报
回复
[Quote=引用 35 楼 ghost5216 的回复:]

你还是查查代码是否有资源竞争引起死锁。

[/Quote]

赞同
ghost5216 2011-09-23
  • 打赏
  • 举报
回复
Thread.Sleep(1000);
表示线程释放CPU1000毫秒,但是无法保证1000ms之后该线程会立即获得CPU来继续执行程序,实际上是1000+n ms,n>=0
因为windows是多线程 抢占式。
虽然你想在1000ms之后获得CPU但这时CPU可能正在执行别的线程,所以你的线程不一定会立即获得CPU。

但如你所说的几分钟或几小时这种情况多半不可能。
你还是查查代码是否有资源竞争引起死锁。
你34楼的代码虽然执行时间不可能百分百精准,但1秒左右应该是没什么问题的。
chen_ya_ping 2011-09-23
  • 打赏
  • 举报
回复
10个线程的话,你还不如试试开2个task,每个task负责5个文件的操作。
天祈 2011-09-23
  • 打赏
  • 举报
回复
我觉得这边的处理的数据并不多,起是个线程有大炮打蚊子的感觉!
chichenzhe 2011-09-23
  • 打赏
  • 举报
回复
不应该使用程序为主的方式去实现,而应当考虑 sql server 自行解决.

你的需求无非就是为了 体现出你关心的部分数据库的实时变化,想把变化记录到文本文件里

下面几点可以缓解你 毫无效率的 海量查询数据库与海量IO读写文件操作.

1,数据库某表的数据发生变化之后 通知机制 (肯定可以实现,具体请咨询相关数据库的DBA)
2,把检索数据库变化的模块 与 写入文件的模块进行逻辑拆分,设计的目的就是错开2者的阻塞.防止A模块阻塞的时候B模块跟着阻塞.(说白了就是1个检索模块负责检索数据 并丢入池里面. 另外一个模块到这个池里面来取)

总之,你对数据库分10个线程访问,每秒1次去检索表的操作非常要不得. 这还是你数据量太小,如果大点,实在不敢想象会慢成什么样子.
sunny906 2011-09-22
  • 打赏
  • 举报
回复
To zyloveyrf and everyone:
像这个问题,该如何设计,才能保证每个线程都能即时执行到,不至于使某个或某几个线程里的方法等待很久(可能是几分钟,也可能是几个小时)才会执行
这是最开始的写法:


private void Start1()
{
while(true)
{
//读数据,写数据
Thread.Sleep(1000);
}
}
private void Start2()
{
while(true)
{
//读数据,写数据
Thread.Sleep(1000);
}
}
... ...
private void Start10()
{
while(true)
{
//读数据,写数据
Thread.Sleep(1000);
}
}

private void button1_Click(object sender, EventArgs e)
{
Thread thread1 = new Thread(new ThreadStart(Start1));
thread1.Start();

Thread thread2 = new Thread(new ThreadStart(Start2));
thread2.Start();
.. ...

Thread thread10 = new Thread(new ThreadStart(Start10));
thread10.Start();
}
萧炎 2011-09-22
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 sunny906 的回复:]
谢谢zyloveyrf
感觉自己对多线程理解不够,正如sp1234所说的,“没有能够真正去在多线程条件下正确地设计程序”
[/Quote]

其实线程不是想象的那么难 LZ稍微注意点就OK拉
sunny906 2011-09-22
  • 打赏
  • 举报
回复
TO ilyzsq:
我们出现的问题可能一样,应该是代码设计不够严谨
ilyzsq 2011-09-22
  • 打赏
  • 举报
回复
最近也在做多线程,上位机与下位机通讯,单个测试很好,一到现场就出问题,多了就出问题,老是一段时间存不进去数据,断点也不好找出问题...
sunny906 2011-09-22
  • 打赏
  • 举报
回复
谢谢zyloveyrf
感觉自己对多线程理解不够,正如sp1234所说的,“没有能够真正去在多线程条件下正确地设计程序”
萧炎 2011-09-22
  • 打赏
  • 举报
回复

public static void ThreadFunc()
{
// 线程停止运行的标志位.
Boolean done = false;

// 计数器
int count = 0;

while (!done)
{
// 休眠1秒.
Thread.Sleep(1000);

// 计数器递增
count++;

// 输出.
Console.WriteLine("[静态]执行次数:{0}", count);
}
}


/// <summary>
/// 启动线程的代码.
/// </summary>
public static void StartThread()
{
ThreadStart ts = new ThreadStart(ThreadFunc);
Thread t = new Thread(ts);

// 启动.
t.Start();
}
萧炎 2011-09-22
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 sunny906 的回复:]
如果多线程写成如下的两种方法(button1_Click和button2_Click),有什么区别吗?

C# code


private void Start1()
{
while(true)
{
//方法
}
}……
[/Quote]
没什么区别 都是先执行1 在执行2 ....10
sunny906 2011-09-22
  • 打赏
  • 举报
回复
如果多线程写成如下的两种方法(button1_Click和button2_Click),有什么区别吗?

private void Start1()
{
while(true)
{
//方法
}
}
private void Start2()
{
while(true)
{
//方法
}
}
... ...
private void Start10()
{
while(true)
{
//方法
}
}

private void button1_Click(object sender, EventArgs e)
{
Thread thread1 = new Thread(new ThreadStart(Start1));
thread1.Start();

Thread thread2 = new Thread(new ThreadStart(Start2));
thread2.Start();
.. ...

Thread thread10 = new Thread(new ThreadStart(Start10));
thread10.Start();
}

private void button2_Click(object sender, EventArgs e)
{
Thread thread1 = new Thread(new ThreadStart(Start1));
Thread thread2 = new Thread(new ThreadStart(Start2));
.. ...

Thread thread10 = new Thread(new ThreadStart(Start10));

thread1.Start();
thread2.Start();
... ...
thread10.Start();

thread1.Join();
thread2.Join();
... ...
thread10.Join();
}

肖无疾 2011-09-21
  • 打赏
  • 举报
回复
很好奇用来干嘛的,如此频繁的生成文件
每秒的请求总大于1吗
showjim 2011-09-21
  • 打赏
  • 举报
回复
如果是这样,两个线程就够了,一个线程查数据,一个线程写文件
ghost5216 2011-09-21
  • 打赏
  • 举报
回复
那你没必要用多线程,
线程越多处理反而越慢了
sunny906 2011-09-21
  • 打赏
  • 举报
回复
是这样的,在多线程并发访问数据库的时候,有一个公共的线程锁对象,如果有一个线程执行查询操作,就会锁定该对象,也就是数据库每次只能给一个线程提供查询,其他线程要等到正在查询的线程查完数据后,才能执行自己的查询操作;会不会因为线程查询频繁,导致某个或某几个线程无限期等待,也就是某些数据根本就没有被读到?
showjim 2011-09-21
  • 打赏
  • 举报
回复
100个线程的开销相对于你的需求真的可以说是九牛一毛,再说你的主要操作是IO,CPU空着也是空着。
还是找出真正影响效率的地方吧,比如是不是数据查询太慢,是不是文件本来就很大。
fangshaoshen 2011-09-21
  • 打赏
  • 举报
回复
我觉得楼主该检查下为什么会出现 没有重写(更新)的情况
加载更多回复(20)

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧