ironpython2 icon indicating copy to clipboard operation
ironpython2 copied to clipboard

ANSYS Workbench Ironpython threading problem

Open 1990chs opened this issue 4 years ago • 7 comments

Description

ANSYS Workbench use Ironpython language to develop extension and I try to use threading modulus to improve calculating speed(most are I/O tasks). But it seems that the multi threading don't work.

Steps to Reproduce

  1. First I build a classic as follow:
import threading

class MyThread(threading.Thread):
    def __init__(self, func, args, name=''):
        threading.Thread.__init__(self)
        self.name = name
        self.func = func
        self.args = args

    def getResult(self):
        return self.result

    def run(self):
        self.result = self.func(*self.args)
  
  1. Then I use the following way to use it:
from myThread import MyThread
results = []
for i in range(3):
    t = MyThread(funcs[i], (q, nloops)_)
    t.start()
    t.join()
    results.append(t.getResult())

I can get the right result, but the calculate speed don't improve. It is almost same speed with no using thread.

Versions

IronPython 2.7.0.40 on .NET 4.0.30319.42000 The version is very old and it is the ANSYS Workbench contain, so I ca't update it to the lasting version.

屏幕截图 2021-06-06 111815

1990chs avatar Jun 06 '21 03:06 1990chs

You are misusing threading. t.join will block until the thread terminates so it's as if you weren't using threading at all. You need to do something like:

threads = []
for i in range(3):
    t = MyThread(funcs[i], (q, nloops)_)
    t.start()
    thread.append(t)

for t in threads:
    t.join()
    results.append(t.getResult())

slozier avatar Jun 06 '21 13:06 slozier

You are misusing threading. t.join will block until the thread terminates so it's as if you weren't using threading at all. You need to do something like:

threads = []
for i in range(3):
    t = MyThread(funcs[i], (q, nloops)_)
    t.start()
    thread.append(t)

for t in threads:
    t.join()
    results.append(t.getResult())

MyThread(funcs[i], (q, nloops)_) for i in range(3)]

I put t.join() and t.start() in one loop. you mean they should be on different loop ?

1990chs avatar Jun 07 '21 01:06 1990chs

I put t.join() and t.start() in one loop. you mean they should be on different loop ?

Yes. One loop starts all your threads and the other loop wait for them to end.

slozier avatar Jun 07 '21 13:06 slozier

I put t.join() and t.start() in one loop. you mean they should be on different loop ?

Yes. One loop starts all your threads and the other loop wait for them to end.

Thinks! I will try it

1990chs avatar Jun 08 '21 02:06 1990chs

I put t.join() and t.start() in one loop. you mean they should be on different loop ?

Yes. One loop starts all your threads and the other loop wait for them to end.

I have try it. It seems the speed is the same without using thread, I don't know why . This version ironPython don't have multiprocessing modulus, so sad. So, is there any way to improve calculate speed ?

1990chs avatar Jun 08 '21 06:06 1990chs

you can try to use Net framework with AsParallel() (extension System.Linq) https://docs.microsoft.com/fr-fr/dotnet/api/system.linq.parallelenumerable.asparallel?view=net-5.0

an example

import clr
import sys
clr.AddReference("System.Core")
import System
clr.ImportExtensions(System.Linq)
from System.IO import *
from System.Net import *
import time

request = WebRequest.Create("https://www.gutenberg.org/files/65568/65568-0.txt")
with request.GetResponse() as response:	 
	with response.GetResponseStream() as stream:
		with StreamReader(stream) as reader:
			html = reader.ReadToEnd()
			html = html.encode("utf-8")
					
def counterWords(chrt, lstTxt):
	chrt = chrt.encode("utf-8")
	count_ = lstTxt.count(chrt)
	return [chrt, count_]
			
searchCharacs = ["the","on","a","in","day","this", "of", "his", "and", "he", "when", "it", "an", "she", "not", "you"]
# make a big list
searchCharacs = searchCharacs * 10
lstTxt = html.split()
# test without AsParallel
print("test without AsParallel")
start = time.time()
result =[]
for s in searchCharacs:
	result.append(counterWords(s, lstTxt))
elapse = ("%s s" % (time.time()-start))
print(elapse)

# test with AsParallel
print("test with AsParallel")
start2 = time.time()
threadResult = searchCharacs.AsParallel().Select(lambda searchC: counterWords(searchC, lstTxt))
elapse2 = ("%s s" % (time.time()-start2))
# print the result
# print(list(threadResult))
print(elapse2)

my result time image

Cyril-Pop avatar Jun 09 '21 07:06 Cyril-Pop

you can try to use Net framework with AsParallel() (extension System.Linq) https://docs.microsoft.com/fr-fr/dotnet/api/system.linq.parallelenumerable.asparallel?view=net-5.0

an example

import clr
import sys
clr.AddReference("System.Core")
import System
clr.ImportExtensions(System.Linq)
from System.IO import *
from System.Net import *
import time

request = WebRequest.Create("https://www.gutenberg.org/files/65568/65568-0.txt")
with request.GetResponse() as response:	 
	with response.GetResponseStream() as stream:
		with StreamReader(stream) as reader:
			html = reader.ReadToEnd()
			html = html.encode("utf-8")
					
def counterWords(chrt, lstTxt):
	chrt = chrt.encode("utf-8")
	count_ = lstTxt.count(chrt)
	return [chrt, count_]
			
searchCharacs = ["the","on","a","in","day","this", "of", "his", "and", "he", "when", "it", "an", "she", "not", "you"]
# make a big list
searchCharacs = searchCharacs * 10
lstTxt = html.split()
# test without AsParallel
print("test without AsParallel")
start = time.time()
result =[]
for s in searchCharacs:
	result.append(counterWords(s, lstTxt))
elapse = ("%s s" % (time.time()-start))
print(elapse)

# test with AsParallel
print("test with AsParallel")
start2 = time.time()
threadResult = searchCharacs.AsParallel().Select(lambda searchC: counterWords(searchC, lstTxt))
elapse2 = ("%s s" % (time.time()-start2))
# print the result
# print(list(threadResult))
print(elapse2)

my result time image

Thinks. I will try.

1990chs avatar Jun 10 '21 05:06 1990chs