线程导致主函数卡顿的问题

zjgdtl 2015-04-15 01:13:00
标题不好说清楚,目前我遇到了一个棘手的问题
写了一个程序,主函数里有一个通信回调的函数,会一直调用我的回调函数
同时代码里面有一块定时循环刷新数据库,我是用线程,每5秒刷新一次
这些根据需求运行在网站的后台

我在我电脑上运行都没问题,虽然cpu负荷比较高,但是程序正常
但是在服务器上运行,回调函数就会卡顿,本来比如1s一次,现在3-4秒都进不去,导致时间不准
我把循环的那块代码注释之后,回调函数正常

但是奇怪的问题是,我的电脑配置远没有服务器好,但我电脑上是正常的,服务器上却有问题
有没有人遇到过这样的情况,求老司机
...全文
251 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
kevinmartin 2015-04-15
  • 打赏
  • 举报
回复
引用 9 楼 zjgdtl 的回复:
[quote=引用 7 楼 kevinmartin 的回复:] [quote=引用 6 楼 zjgdtl 的回复:] 并没有什么关系啊,其实我就是搞不懂为什么同样的代码,不同的机器上有不同的结果,线程里面实在不好控制
不知道怎么问问题,不知道怎么回答问题 没有关系的话,2个线程怎么会相互影响的呢? 回调什么时候被执行?谁trigger的? [/quote] 那个回调函数就像websocket 一样,是我连接的上位机主动发的,不过这个也不用深究的,实际上就是性能问题,你们在处理那个不断循环数据库的时候有没有不用线程或者定时器的方式,或者有没有办法让我这一块完全独立[/quote] 我再尝试理解一下: 回调是独立触发的一个东西,其执行过程在主线程中(ignore) 你有一个线程在不停地跑数据库(假设这个刷的内容是下位机发过来的某个数据,在回调中也要写到数据库里的) 设计一种case: 某个工控机在想你发送某个设备的信息,比如说不停地发送电压数据,你的回调收到以后存到数据库里。(同时,我猜测你存到数据库中会有一个时间字段,这个数据保存的是你存的那一刻的数据,而不是下位机传上来的数据)这是你的主要问题 同时你还有一个线程在不停地刷数据库,取这个数据最近的记录,用于在你的界面上显示一个图标,假设(>100V的时候显示红灯,<100V的时候显示绿灯) 那么这之间可能存在的问题,我尝试一一列出来: 1. 数据库的锁,对同一个表的读写锁可能会有锁的性能问题。 2. 是不是上服务器以后连的下位机的数量变多了,导致对数据库的访问量增大,从而导致1的性能问题 3. 线程本身对数据库操作的优化不够(sql调优) 4. 针对2的问题,线程调度出现加锁解锁的性能问题 建议查看CPU,如果CPU是占用2核的100%以上(比如4核就是50%以上,8核就是25%以上),就说明是程序的性能问题 如果只有1核的100%以上,那就是数据库的性能问题(一般是磁盘性能) 跑一跑,给系统资源的情况列出来看看
xuzuning 2015-04-15
  • 打赏
  • 举报
回复
1、回调没有立即执行,可能是你的程序在消息链中的级别偏低了 好像有一个 api 可以让程序立即响应系统消息 2、既然有回调,就应采用异步方式进行通讯,不要 while 循环等待。
zjgdtl 2015-04-15
  • 打赏
  • 举报
回复
引用 7 楼 kevinmartin 的回复:
[quote=引用 6 楼 zjgdtl 的回复:] 并没有什么关系啊,其实我就是搞不懂为什么同样的代码,不同的机器上有不同的结果,线程里面实在不好控制
不知道怎么问问题,不知道怎么回答问题 没有关系的话,2个线程怎么会相互影响的呢? 回调什么时候被执行?谁trigger的? [/quote] 那个回调函数就像websocket 一样,是我连接的上位机主动发的,不过这个也不用深究的,实际上就是性能问题,你们在处理那个不断循环数据库的时候有没有不用线程或者定时器的方式,或者有没有办法让我这一块完全独立
潇潇雨云 2015-04-15
  • 打赏
  • 举报
回复
kevinmartin 2015-04-15
  • 打赏
  • 举报
回复
引用 6 楼 zjgdtl 的回复:
并没有什么关系啊,其实我就是搞不懂为什么同样的代码,不同的机器上有不同的结果,线程里面实在不好控制
不知道怎么问问题,不知道怎么回答问题 没有关系的话,2个线程怎么会相互影响的呢? 回调什么时候被执行?谁trigger的?
zjgdtl 2015-04-15
  • 打赏
  • 举报
回复
并没有什么关系啊,其实我就是搞不懂为什么同样的代码,不同的机器上有不同的结果,线程里面实在不好控制
kevinmartin 2015-04-15
  • 打赏
  • 举报
回复
引用 4 楼 zjgdtl 的回复:
[quote=引用 2 楼 kevinmartin 的回复:] 这个描述实在太。。。。。。。。 我尝试纠错理解: 所谓的主函数是主程序,即常说的主线程 主线程的某个函数注册了某个回调,即根据某个信号或者时间进行回调,回调函数是另外写的。 剩下的就完全是猜测了: 我猜到2种可能性: 1. 刷数据库的函数在回调中,lz在回调函数中开了一个线程刷数据库,这个回调在等这个线程结束后再返回 2. 刷数据库的函数在和主线程并行的一个线程中,开定时器5秒刷一次,刷出结果后发送一个事件,之前那个回调执行。 看到后面的描述,个人感觉1的可能性比较大。 下面按照1的情况分析: 最关键的一点,我发现一个地方有冲突:如果在回调中开线程,那么回调不会卡顿,这是有矛盾的地方。所有我猜测一种弱智的错误发生的情况:因为回调是在主线程中的,所以回调执行的时候开新线程,然后在回调中waitForExit死等线程结束,造成主线程被卡死 上面是说的逻辑错误的地方 那么问题来了,为什么服务器慢,本机快呢?根据提供的信息猜测:两边的数据库的数量不一样,本地调试的数据库只有10条记录,服务器有100万条记录。
数据库是同一个啊,我在简单说明一下 比如主函数 main { 注册了一个回调() 线程1.start() } 线程1 { whille(true) { foo(); thread.sleep(5000) } } 就这种结构,关键是在我的烂电脑上完全没问题,在性能优越的服务器上,回调函数总是不能及时调用 把线程注释掉,回调函数正常[/quote] 看来是第二种情况了,线程和回调之间是什么关系?
zjgdtl 2015-04-15
  • 打赏
  • 举报
回复
引用 2 楼 kevinmartin 的回复:
这个描述实在太。。。。。。。。 我尝试纠错理解: 所谓的主函数是主程序,即常说的主线程 主线程的某个函数注册了某个回调,即根据某个信号或者时间进行回调,回调函数是另外写的。 剩下的就完全是猜测了: 我猜到2种可能性: 1. 刷数据库的函数在回调中,lz在回调函数中开了一个线程刷数据库,这个回调在等这个线程结束后再返回 2. 刷数据库的函数在和主线程并行的一个线程中,开定时器5秒刷一次,刷出结果后发送一个事件,之前那个回调执行。 看到后面的描述,个人感觉1的可能性比较大。 下面按照1的情况分析: 最关键的一点,我发现一个地方有冲突:如果在回调中开线程,那么回调不会卡顿,这是有矛盾的地方。所有我猜测一种弱智的错误发生的情况:因为回调是在主线程中的,所以回调执行的时候开新线程,然后在回调中waitForExit死等线程结束,造成主线程被卡死 上面是说的逻辑错误的地方 那么问题来了,为什么服务器慢,本机快呢?根据提供的信息猜测:两边的数据库的数量不一样,本地调试的数据库只有10条记录,服务器有100万条记录。
数据库是同一个啊,我在简单说明一下 比如主函数 main { 注册了一个回调() 线程1.start() } 线程1 { whille(true) { foo(); thread.sleep(5000) } } 就这种结构,关键是在我的烂电脑上完全没问题,在性能优越的服务器上,回调函数总是不能及时调用 把线程注释掉,回调函数正常
zjgdtl 2015-04-15
  • 打赏
  • 举报
回复
引用 1 楼 xdashewan 的回复:
你有没确认是否进入你的通信回调的函数,没进通信回调的函数和进入通信回调的函数执行卡顿是完全不同的,前者你要查通讯问题,后者你要查通信回调的函数里的逻辑问题
没有进入,其实那个回调函数是一个报警的回调函数,必须要实时,因为线程那块在循环,所以回调函数呈现出的结果是延迟进入,比如我本来1分钟进了2次,最终呈现出来就是2分钟进了两次,之后的也都因这样延迟了
kevinmartin 2015-04-15
  • 打赏
  • 举报
回复
这个描述实在太。。。。。。。。 我尝试纠错理解: 所谓的主函数是主程序,即常说的主线程 主线程的某个函数注册了某个回调,即根据某个信号或者时间进行回调,回调函数是另外写的。 剩下的就完全是猜测了: 我猜到2种可能性: 1. 刷数据库的函数在回调中,lz在回调函数中开了一个线程刷数据库,这个回调在等这个线程结束后再返回 2. 刷数据库的函数在和主线程并行的一个线程中,开定时器5秒刷一次,刷出结果后发送一个事件,之前那个回调执行。 看到后面的描述,个人感觉1的可能性比较大。 下面按照1的情况分析: 最关键的一点,我发现一个地方有冲突:如果在回调中开线程,那么回调不会卡顿,这是有矛盾的地方。所有我猜测一种弱智的错误发生的情况:因为回调是在主线程中的,所以回调执行的时候开新线程,然后在回调中waitForExit死等线程结束,造成主线程被卡死 上面是说的逻辑错误的地方 那么问题来了,为什么服务器慢,本机快呢?根据提供的信息猜测:两边的数据库的数量不一样,本地调试的数据库只有10条记录,服务器有100万条记录。
xdashewan 2015-04-15
  • 打赏
  • 举报
回复
你有没确认是否进入你的通信回调的函数,没进通信回调的函数和进入通信回调的函数执行卡顿是完全不同的,前者你要查通讯问题,后者你要查通信回调的函数里的逻辑问题

110,538

社区成员

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

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

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