none
为啥我开启一个线程CPU正常,只要开启多线程,cpu占用就100%了,但是程序能正常工作?徒弟不才,各位老师帮帮忙! RRS feed

  • 问题

  • private void button1_Click(object sender, EventArgs e)
            {
                if (!string.IsNullOrEmpty(this.richTextBox1.Text))
                {
                    string[] strlist = this.richTextBox1.Text.Replace(",",",").Split(',');
                    foreach (string item in strlist)
                    {
                        list.Add(item.ToString());
                    }
                    ThreadCount = Convert.ToInt32(this.numericUpDown1.Value);
                    for (int i = 0; i < ThreadCount; i++)
                    {
                        th = new Thread(new ThreadStart(Analyasis));
                        th.IsBackground = true;
                        th.Start();
                    }
                    this.timer1.Start();
                }
            }
            private void Analyasis()
            {
                while (true)
                {
                    string kwd = "";
                    if (list.Count > 0)
                    {
                        kwd = list[0].ToString();
                        list.RemoveAt(0);
                    }
                    if (kwd != "")
                    {
                        int num = 100;
                        for (int i = 0; i < 8; i++)
                        {
                            url = "http://news.baidu.com/ns?word=" + kwd + "&pn=" + i * num + "&rn=" + num;
                            pageContent += GetPageContent(url, "utf-8");
                        }
                        if (pageContent != "")
                        {
                            Regex reg = new Regex("", RegexOptions.IgnoreCase);
                            Regex regNameList = new Regex("(?<=<h3 class=\"c-title\">(.|\n)*>).*?(?=</a></h3><span class=\"c-author\">)", RegexOptions.IgnoreCase);
                            MatchCollection mc = regNameList.Matches(pageContent);
                            foreach (Match item in mc)
                            {
                                if (!string.IsNullOrEmpty(item.ToString()))
                                {
                                    result = "";
                                   result = item.ToString().Replace("<em>", "").Replace("</em>", "").Replace("&nbsp;", "");
                                }
                           }
                           result = "已完成......\r\n";
                       }
                  }
              }
           }
                            

    2014年1月14日 1:35

全部回复

  • 你的Analyasis方法应该有break(终止条件)吧?请在合适地方加上,譬如:

    private void Analyasis()
            {
                while (true)
                {
                    string kwd = "";
                    if (list.Count > 0)
                    {
                        kwd = list[0].ToString();
                        list.RemoveAt(0);
                    }
                    if (kwd != "")
                    {
                        int num = 100;
                        for (int i = 0; i < 8; i++)
                        {
                            url = "http://news.baidu.com/ns?word=" + kwd + "&pn=" + i * num + "&rn=" + num;
                            pageContent += GetPageContent(url, "utf-8");
                        }
                        if (pageContent != "")
                        {
                            Regex reg = new Regex("", RegexOptions.IgnoreCase);
                            Regex regNameList = new Regex("(?<=<h3 class=\"c-title\">(.|\n)*>).*?(?=</a></h3><span class=\"c-author\">)", RegexOptions.IgnoreCase);
                            MatchCollection mc = regNameList.Matches(pageContent);
                            foreach (Match item in mc)
                            {
                                if (!string.IsNullOrEmpty(item.ToString()))
                                {
                                    result = "";
                                   result = item.ToString().Replace("<em>", "").Replace("</em>", "").Replace("&nbsp;", "");
                                }
                           }
                           result = "已完成......\r\n";                       break;
                       }
                  }

    另外你的timer1写了什么?


    ASP.NET Questions
    Other Discussions
    FreeRice Donate
    Issues to report
    Free Tech Books Search

    2014年1月14日 5:50
    版主
  • private void timer1_Tick(object sender, EventArgs e)
            {
                this.timer1.Stop();
                this.richTextBox2.AppendText(result);
                result = "";
                this.timer1.Start();
            }

    这是timer1里面的
    2014年1月14日 6:26
  • private void timer1_Tick(object sender, EventArgs e) { this.timer1.Stop();

    既然你里边自己把自己都给Stop了,怎么还会启动?


    ASP.NET Questions
    Other Discussions
    FreeRice Donate
    Issues to report
    Free Tech Books Search

    2014年1月14日 6:56
    版主
  • while (true)
     {

    .....

    Thread.Sleep(100);

    试试。

    2014年1月14日 9:12
  • 没用的!开启多线程,CPU仍然直彪100%,郁闷...
    2014年1月14日 9:34
  • 我也不明白到底为什么?有什么办法,开启多个线程,只占一个线程的CPU消耗吗?
    2014年1月14日 9:36
  • 我也不明白怎么回事!有没有办法,开始多线程,只占一个线程的CPU消耗?
    2014年1月14日 9:40
  • 是不是和正则表达式有关系呢?单线程下cpu占用率有多高,优化下正则表达式看看,我之前也遇到过相似的问题,因为正则表达式写的不好,程序执行了很长时间正则表达式才匹配完。

    好像是 while 循环问题,

    if (list.Count > 0)
    {
         kwd
    = list[0].ToString();
          list
    .RemoveAt(0);
    }

    当所有的关键字从 list 中全部移除之后,list.Count == 0,

    if (list.Count > 0)
    {

    }

      if (kwd != "")
      
    {
       }

    在 while 循环中上面的两个if 语句都不会被执行,

    只执行了 string kwd = ""; 这一句
    你的 while 是一个死循环,没有退出循环的代码,可能导致 CPU 占用率 100%。

    就算只开启一个线程,while 也不会退出啊,cpu 占用率应该也不会太低吧。

    另外还一个是不是和多线程的死锁有关系。

    我能想到的就这几点了



    Janfrayda Yu


    • 已编辑 janfrayda 2014年1月14日 13:58 修改,补充
    2014年1月14日 13:35
  • 恩,谢谢!我开启单线程的时候CPU占用大概是35+%,执行速度也很快!另外我看到一个类似程序执行多线程和单线程的CPU占用是一样的,我就搞不明白了,就是看不到它的源代码!你这么一说,我也感觉while循环有点问题,但具体怎么改?求师傅指教

    2014年1月15日 1:49
  • 你好:

    如果去掉正则表达式那段代码CPU占用率是否还是那么高呢?

    我觉得你可以一步一步去调试你的程序,先找出占用CPU高的代码段,然后再想办法去优化它。

    而且你在timer的Tick方法中先停止再启动,不太明白你为什么要这样做。


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年1月15日 2:33
    版主
  • 先试试在 if 后面 加上 else 如果 list.Count == 0 就退出循环

    if (list.Count > 0)
    {

    ...

    }

     else     //  加上这段退出循环

    {

         return;

    }


    Janfrayda Yu

    2014年1月15日 3:21
  • 加上退出循环还是不行,开启多线程,CPU直接100%,纳闷了
    2014年1月15日 5:42
  • 这种情况就像版主建议的那样,一点点调试了,找出最后的问题。

    感觉现在最主要的就是采集的部分和正则表达式的部分,你可以先把正则表达式注释掉,看看 cpu 占用率还有多高?如果不是正则表达式的问题,再看看你的采集代码有没有问题


    Janfrayda Yu

    2014年1月15日 5:54
  • foreach (Match item in mc)
                            {
                                if (!string.IsNullOrEmpty(item.ToString()))
                                {
                                    result = "";
                                   result = item.ToString().Replace("<em>", "").Replace("</em>", "").Replace("&nbsp;", "");
                                }
                           }
    
    是不是这一段遍历有问题吧?我执行这段的时候,CPU90%,其他时间CPU不到50%
    2014年1月15日 6:49
  • 首先删除:

    result = "";

    其次,代码看没有问题。不知道你正则是否死循环?断点单独调试正则看看。正如之前几位说的一样,谢谢!


    ASP.NET Questions
    Other Discussions
    FreeRice Donate
    Issues to report
    Free Tech Books Search

    2014年1月15日 6:55
    版主
  • 恩!是的,谢谢了,是正则表达式的问题,现在正在找合适的正则表达式,谢谢了!

    2014年1月16日 6:07
  • 你需要完成什么任务采用正则?可以举例子说明吗?

    ASP.NET Questions
    Other Discussions
    FreeRice Donate
    Issues to report
    Free Tech Books Search

    2014年1月16日 8:38
    版主
  • 谢谢了!正则自己找到了!
    2014年1月20日 9:29
  • private void Analyasis()
            {
                while (true)
                {
                    string kwd = "";
                    if (list.Count > 0)
                    {
                        kwd = list[0].ToString();
                        list.RemoveAt(0);
                    }
                    if (kwd != "")
                    {
                        int num = 100;
                        for (int i = 0; i < 8; i++)
                        {
                            url = "http://news.baidu.com/ns?word=" + kwd + "&pn=" + i * num + "&rn=" + num;
                            pageContent += GetPageContent(url, "utf-8");
                        }
                        if (pageContent != "")
                        {
                            Regex reg = new Regex("", RegexOptions.IgnoreCase);
                            Regex regNameList = new Regex("<h3 class=\"c-title\"><a[^>]+>(?<note>.+?)</a>", RegexOptions.IgnoreCase);
                            MatchCollection mc = regNameList.Matches(pageContent);
                            foreach (Match item in mc)
                            {
                                if (!string.IsNullOrEmpty(item.ToString()))
                                {
                                    result = "";
                                    j++;
                                    result = item.Groups["note"].Value.ToString().Replace("<em>", "").Replace("</em>", "").Replace("&nbsp;", "").Replace("&quot;", "") + "\r\n";
                                    this.txt.Text += result;
                               
                                    Keyword key = new Keyword();
                                    key.ID = j;
                                  
                                    key.Title = result;
                               
                                    li.Add(key);
                                    
                                    this.lbl.Text = "共" + j + "条";
                                    
                                }
                            }
                            this.txt.Text += "已完成......\r\n";
                            Save(li);
                        }
                    }
                    else
                    {
                        return;
                    }
                }
            }
    	private void Save(List<Keyword> li)
            {
                OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Users\\Administrator\\Desktop\\news.mdb");
                con.Open();
                OleDbCommand cmd = new OleDbCommand();
                cmd.Connection = con;
                foreach (Keyword word in li)
                {
                    sql = string.Format("insert into newstitle(id,title) values({0},'{1}')", word.ID, word.Title);
    		cmd.CommandText = sql;
                    cmd.ExecuteNonQuery();
                }
                con.Close();
            }
    开启三个线程,抓取的数据就不完整,并且入库也有问题,为什么呢?求师傅们指教
    2014年1月20日 9:35
  • 可以分享一下就标记自己为答案,可以结贴了,呵呵。

    ASP.NET Questions
    Other Discussions
    FreeRice Donate
    Issues to report
    Free Tech Books Search

    2014年1月21日 3:04
    版主
  • hello,

    您的connect开开关关的,建议您循环处理完毕後在关

    没看到您thread怎麽写的

    您是要多线程处理同一个档案?


    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/


    2014年1月21日 3:36
  • connect 就是在循环外面呀!线程是根据关键字设置的
    private void button1_Click(object sender, EventArgs e)
            {
                if (!string.IsNullOrEmpty(this.richTextBox1.Text))
                {
                    string[] strlist = this.richTextBox1.Text.Replace(",",",").Split(',');
                    foreach (string item in strlist)
                    {
                        list.Add(item.ToString());
                    }
                    ThreadCount = Convert.ToInt32(this.numericUpDown1.Value);
                    for (int i = 0; i < ThreadCount; i++)
                    {
                        th = new Thread(new ThreadStart(Analyasis));
                        th.IsBackground = true;
                        th.Start();
                    }
                    //this.timer1.Start();
                }
            }
    这是线程的代码
    2014年1月21日 6:00
  • 多线程去执行重复的代码片段得到的结果因为不同线程轮转导致数据冗余或者偏差。我建议你只用一个后台线程处理就可以了。或者你可以设法获取数据长度,然后创建一个大数组,用多线程分片填入指定的区域,最后得到一个完整的数组数据也可以。


    ASP.NET Questions
    Other Discussions
    FreeRice Donate
    Issues to report
    Free Tech Books Search

    2014年1月21日 7:34
    版主
  • 如果只用一个的线程的话,速度有点慢吧!另外你说的获取数据长度,用多线程分片填入到数据里面,这个不明白什么意思...

    2014年1月22日 1:40
  • 如果你知道了数据类型和长度(比如总长度1000,那么你可以定义某种类型的数组,容量1000),你可以开辟5个线程,每个线程分别填充数组的一部分(比如线程1填充0~199,线程2填充200~399……),每个线程填充整个数组的一部分,当全部完成了,自然任务也就完成了。注意可能需要使用自定义事件告知任务已经完成。

    ASP.NET Questions
    Other Discussions
    FreeRice Donate
    Issues to report
    Free Tech Books Search


    2014年1月22日 2:10
    版主
  • 恩!方法还是可以的,但有局限性,不知道数据长度的不能这样操作吧!
    2014年1月22日 5:53
  • MatchCollection应该有Count属性吧?你就可以利用它创建数组,然后再用线程分别操作。

    ASP.NET Questions
    Other Discussions
    FreeRice Donate
    Issues to report
    Free Tech Books Search

    2014年1月22日 6:00
    版主
  • 大神,我抓取数据的时候用线程抓取的,再用现成来操作数组,相当于线程里面嵌套线程,这样能行吗?
    2014年1月22日 6:27
  • 抓数据(如果你的正则表达式不复杂),应该很快可以抓取长度,然后再开辟线程操作。

    ASP.NET Questions
    Other Discussions
    FreeRice Donate
    Issues to report
    Free Tech Books Search

    2014年1月22日 6:43
    版主
  • 正则不复杂,但是得开多线程抓取数据,两个线程的时候程序正常,但是只要一开三个以上的线程就不行了!
    2014年1月22日 8:12
  • 你先用正则获取长度,然后定义空数组,然后分区块抓取数据。注意不要重叠。

    ASP.NET Questions
    Other Discussions
    FreeRice Donate
    Issues to report
    Free Tech Books Search

    2014年1月22日 8:14
    版主