none
如何进行多线程编程? RRS feed

  • 问题

  •  对彩票有研究的大虾们对下面的这段代码肯定不会陌生,这段代码的意思是从七个数组里分别提取0-3个数组合成一个含七个数的组合,最后的组合量非常庞大,在运行时N长时间里,根本没有反应,如果把数据量减少,则运行很正常,说明这段代码没有问题,我对多线程不是很了解,但我感觉如果把这个任务放到几个线程上面同时执行的话,效率肯定会提高很多.请问高们多线程应该如何设置呀?另外,如果这个问题不用到多线程技术的话,要达到同样的目的,有什么更好的算法吗?

     Dim a As Integer()() = New Integer(6)() {}

       Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
          a(0) = New Integer() {3, 7, 12, 14, 16, 24}
          a(1) = New Integer() {1, 5, 11, 19, 26}
          a(2) = New Integer() {2, 8, 13, 17}
          a(3) = New Integer() {4, 6, 20, 25}
          a(4) = New Integer() {9, 15, 23, 28}
          a(5) = New Integer() {10, 22, 27, 30}
          a(6) = New Integer() {18, 21, 26, 29}
          For i As Integer = 0 To a.GetUpperBound(0)
             For j As Integer = 0 To a.GetUpperBound(0)
                For k As Integer = 0 To a.GetUpperBound(0)
                   For m As Integer = 0 To a.GetUpperBound(0)
                      If i <> j And i <> k And i <> m And j <> k And j <> m And k <> m Then
                         p3211(a(i), a(j), a(k), a(m))
                      End If
          Next m, k, j, i
          Label1.Text = ListBox1.Items.Count
       End Sub

       Sub p3211(ByVal a1 As Integer(), ByVal a2 As Integer(), ByVal a3 As Integer(), ByVal a4 As Integer())
          Dim a7 As Integer() = New Integer(6) {}
          For a As Integer = 0 To a1.GetUpperBound(0) - 2
             For b As Integer = a + 1 To a1.GetUpperBound(0) - 1
                For c As Integer = b + 1 To a1.GetUpperBound(0)
                   For d As Integer = 0 To a2.GetUpperBound(0) - 1
                      For e As Integer = d + 1 To a2.GetUpperBound(0)
                         For f As Integer = 0 To a3.GetUpperBound(0)
                            For g As Integer = 0 To a4.GetUpperBound(0)
                               a7(0) = a1(a)
                               a7(1) = a1(b)
                               a7(2) = a1(c)
                               a7(3) = a2(d)
                               a7(4) = a2(e)
                               a7(5) = a3(f)
                               a7(6) = a4(g)
                               Array.Sort(a7)
                               ListBox1.Items.Add(Format(a7(0), "00") & " " & Format(a7(1), "00") & " " & Format(a7(2), "00") & " " & _
                               Format(a7(3), "00") & " " & Format(a7(4), "00") & " " & Format(a7(5), "00") & " " & Format(a7(6), "00"))
          Next g, f, e, d, c, b, a             
       End Sub


    xrhigh
    2009年2月20日 2:21

答案

  • 爱的就是你 说:

     对彩票有研究的大虾们对下面的这段代码肯定不会陌生,这段代码的意思是从七个数组里分别提取0-3个数组合成一个含七个数的组合,最后的组合量非常庞大,在运行时N长时间里,根本没有反应,如果把数据量减少,则运行很正常,说明这段代码没有问题,我对多线程不是很了解,但我感觉如果把这个任务放到几个线程上面同时执行的话,效率肯定会提高很多.请问高们多线程应该如何设置呀?另外,如果这个问题不用到多线程技术的话,要达到同样的目的,有什么更好的算法吗?

     Dim a As Integer()() = New Integer(6)() {}

       Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
          a(0) = New Integer() {3, 7, 12, 14, 16, 24}
          a(1) = New Integer() {1, 5, 11, 19, 26}
          a(2) = New Integer() {2, 8, 13, 17}
          a(3) = New Integer() {4, 6, 20, 25}
          a(4) = New Integer() {9, 15, 23, 28}
          a(5) = New Integer() {10, 22, 27, 30}
          a(6) = New Integer() {18, 21, 26, 29}
          For i As Integer = 0 To a.GetUpperBound(0)
             For j As Integer = 0 To a.GetUpperBound(0)
                For k As Integer = 0 To a.GetUpperBound(0)
                   For m As Integer = 0 To a.GetUpperBound(0)
                      If i <> j And i <> k And i <> m And j <> k And j <> m And k <> m Then
                         p3211(a(i), a(j), a(k), a(m))
                      End If
          Next m, k, j, i
          Label1.Text = ListBox1.Items.Count
       End Sub

       Sub p3211(ByVal a1 As Integer(), ByVal a2 As Integer(), ByVal a3 As Integer(), ByVal a4 As Integer())
          Dim a7 As Integer() = New Integer(6) {}
          For a As Integer = 0 To a1.GetUpperBound(0) - 2
             For b As Integer = a + 1 To a1.GetUpperBound(0) - 1
                For c As Integer = b + 1 To a1.GetUpperBound(0)
                   For d As Integer = 0 To a2.GetUpperBound(0) - 1
                      For e As Integer = d + 1 To a2.GetUpperBound(0)
                         For f As Integer = 0 To a3.GetUpperBound(0)
                            For g As Integer = 0 To a4.GetUpperBound(0)
                               a7(0) = a1(a)
                               a7(1) = a1(b)
                               a7(2) = a1(c)
                               a7(3) = a2(d)
                               a7(4) = a2(e)
                               a7(5) = a3(f)
                               a7(6) = a4(g)
                               Array.Sort(a7)
                               ListBox1.Items.Add(Format(a7(0), "00") & " " & Format(a7(1), "00") & " " & Format(a7(2), "00") & " " & _
                               Format(a7(3), "00") & " " & Format(a7(4), "00") & " " & Format(a7(5), "00") & " " & Format(a7(6), "00"))
          Next g, f, e, d, c, b, a             
       End Sub


    xrhigh



    今天刚刚从.net技术大会上得到的确切信息   如果不是多cpu 那么多线没有性能的意义
    如果双核cpu 超过两个线程也都没有意义
    而且建立线程  站用的 内存  gc的消耗   创建和停止的消耗  都很大

    所以往往在一个线程工作   另一个线程留给系统  效率会比较高
    就算首页不能显示30天内排行榜 回答总数也快接近top10了 5555
    努力奋斗 重回首页排行榜!!! 55555
    有原则的回答问题: 不懂的不去装懂,别人回答得很完整的,没有需要补充的不去蹭分。
    2009年2月20日 13:55

全部回复

  • 爱的就是你 说:

     对彩票有研究的大虾们对下面的这段代码肯定不会陌生,这段代码的意思是从七个数组里分别提取0-3个数组合成一个含七个数的组合,最后的组合量非常庞大,在运行时N长时间里,根本没有反应,如果把数据量减少,则运行很正常,说明这段代码没有问题,我对多线程不是很了解,但我感觉如果把这个任务放到几个线程上面同时执行的话,效率肯定会提高很多.请问高们多线程应该如何设置呀?另外,如果这个问题不用到多线程技术的话,要达到同样的目的,有什么更好的算法吗?

     Dim a As Integer()() = New Integer(6)() {}

       Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
          a(0) = New Integer() {3, 7, 12, 14, 16, 24}
          a(1) = New Integer() {1, 5, 11, 19, 26}
          a(2) = New Integer() {2, 8, 13, 17}
          a(3) = New Integer() {4, 6, 20, 25}
          a(4) = New Integer() {9, 15, 23, 28}
          a(5) = New Integer() {10, 22, 27, 30}
          a(6) = New Integer() {18, 21, 26, 29}
          For i As Integer = 0 To a.GetUpperBound(0)
             For j As Integer = 0 To a.GetUpperBound(0)
                For k As Integer = 0 To a.GetUpperBound(0)
                   For m As Integer = 0 To a.GetUpperBound(0)
                      If i <> j And i <> k And i <> m And j <> k And j <> m And k <> m Then
                         p3211(a(i), a(j), a(k), a(m))
                      End If
          Next m, k, j, i
          Label1.Text = ListBox1.Items.Count
       End Sub

       Sub p3211(ByVal a1 As Integer(), ByVal a2 As Integer(), ByVal a3 As Integer(), ByVal a4 As Integer())
          Dim a7 As Integer() = New Integer(6) {}
          For a As Integer = 0 To a1.GetUpperBound(0) - 2
             For b As Integer = a + 1 To a1.GetUpperBound(0) - 1
                For c As Integer = b + 1 To a1.GetUpperBound(0)
                   For d As Integer = 0 To a2.GetUpperBound(0) - 1
                      For e As Integer = d + 1 To a2.GetUpperBound(0)
                         For f As Integer = 0 To a3.GetUpperBound(0)
                            For g As Integer = 0 To a4.GetUpperBound(0)
                               a7(0) = a1(a)
                               a7(1) = a1(b)
                               a7(2) = a1(c)
                               a7(3) = a2(d)
                               a7(4) = a2(e)
                               a7(5) = a3(f)
                               a7(6) = a4(g)
                               Array.Sort(a7)
                               ListBox1.Items.Add(Format(a7(0), "00") & " " & Format(a7(1), "00") & " " & Format(a7(2), "00") & " " & _
                               Format(a7(3), "00") & " " & Format(a7(4), "00") & " " & Format(a7(5), "00") & " " & Format(a7(6), "00"))
          Next g, f, e, d, c, b, a             
       End Sub


    xrhigh



    今天刚刚从.net技术大会上得到的确切信息   如果不是多cpu 那么多线没有性能的意义
    如果双核cpu 超过两个线程也都没有意义
    而且建立线程  站用的 内存  gc的消耗   创建和停止的消耗  都很大

    所以往往在一个线程工作   另一个线程留给系统  效率会比较高
    就算首页不能显示30天内排行榜 回答总数也快接近top10了 5555
    努力奋斗 重回首页排行榜!!! 55555
    有原则的回答问题: 不懂的不去装懂,别人回答得很完整的,没有需要补充的不去蹭分。
    2009年2月20日 13:55
  • 感谢韦恩Baby提供的信息哈,也就是说一般一个UI线程一个工作线程是效率最高的吧


    关于这一大堆代码,我有几个提高运算速度的小意见:
    其实这段代码速度慢的原因很大程度上在于这三个语句:
    Array.Sort
    ListBox1.Items.Add
    Format(xx,xx) & Format(xx,xx)

    (1)Array.Sort方法不必多说,实现为数组排序,肯定会占用大量CPU。暂无改进的建议……= =

    (2)在如此大规模的循环中使用ListBox.Items.Add方法无异于让计算机自杀(- -|||),因为每次调用Add方法时用户界面都要刷新一下以体现属性的更改。闪烁的太频繁的话会造成窗体闪烁并假死的现象。
    解决办法是,在程序的一开始使用ListBox1.BeginUpdate方法,在程序结束后使用ListBox1.EndUpdate方法以避免控件闪烁

    (3)& 连接符会占用大量CPU,而且因为循环次数很多,会产生大量String类型的实例。因为String类的不可变的特性,这些字符串很有可能会触发系统的垃圾收集从而更加拖慢循环执行的速度。建议使用StringBuilder类代替。(话说Format函数内部也是使用的StringBuilder)

    有任何疏漏或者错误或者意见或者建议欢迎提出~

    ***** 欢迎来我的Blog逛逛:http://blog.csdn.net/kaedei  *****
    2009年2月21日 13:42