0
from itertools import product
from multiprocessing import Pool

with Pool(4) as pool:
            pool.map(lambda x: run_test_function(x, arg2, arg3, arg4), arg1)
    

I am getting below error after executing above code. There some other code as well which I can't write here. But actual problem is coming from this piece of code only.

Traceback (most recent call last):
  File "modProfileChange_test.py", line 347, in <module>
    main(sys.argv[1:])
  File "modProfileChange_test.py", line 336, in main
    test_run_code(arg1, arg2, arg3, arg4, arg5, arg6)
  File "modProfileChange_test.py", line 23, in test_run_code
    with Pool(4) as pool:
AttributeError: __exit__
Vanshika
  • 35
  • 7
  • This is already syntactically valid Python 2.7 code – ForceBru Aug 17 '21 at 09:39
  • And what about library used? I am following only your code on another question. So I am not acquainted much with this library. – Vanshika Aug 17 '21 at 09:41
  • nothing special, I guess? This is valid Python 2.7 code – ForceBru Aug 17 '21 at 09:42
  • Its throwing error. – Vanshika Aug 17 '21 at 10:04
  • what's the error? – ForceBru Aug 17 '21 at 10:05
  • Exception: "__exit__" on line: 23 – Vanshika Aug 17 '21 at 11:09
  • 1
    the code you posted only has 5 lines, though. Please post a [mcve] and the _full_ error message (which should start with the word "Traceback"). – ForceBru Aug 17 '21 at 11:11
  • Yeah actually that's lengthy code which I can't share bcoz of intellectual property right issues. But whatever I have posted is the only code which is throwing the exception. Exception had only printed this message which I have posted, if you need more detail on code, then we have to pick some private channel. – Vanshika Aug 17 '21 at 11:15
  • Huh, apparently, it's not possible to pass `lambda` functions to `Pool.map`: https://stackoverflow.com/questions/4827432/how-to-let-pool-map-take-a-lambda-function – ForceBru Aug 17 '21 at 11:35
  • I have edited my question to show the actual error. Can you please reply to this question by answering appropriate code bcoz you know exactly my scenario. – Vanshika Aug 17 '21 at 11:46
  • Ah, so `Pool` is not a context manager in Python 2.7, so it's not possible to use it in a `with` statement. You'll have to write `pool = Pool(4); pool.map(...)` instead – ForceBru Aug 17 '21 at 11:51
  • Even after that lambda won't work. Can you please answer with appropriate code as per my problem as I have lists but not files? – Vanshika Aug 17 '21 at 11:52
  • As I said in a comment above, [`lambda`s don't work with `multiprocessing.Pool`](https://stackoverflow.com/questions/4827432/how-to-let-pool-map-take-a-lambda-function) at all, unfortunately – ForceBru Aug 17 '21 at 12:01
  • That's what I asked, can you please answer with appropriate code as I am following your code only. – Vanshika Aug 17 '21 at 12:10

1 Answers1

2
  1. In Python 2.7, multiprocessing.Pool is not a context manager and thus it can't be used in a with statement
    1. Solution - create a pool using regular assignment to a variable:
      my_pool = Pool(4)
      my_pool.map(...)
      
  2. lambda functions don't work with multiprocessing.Pool, even in Python 3.
    1. Solution - emulate a closure using a solution in the link above:
      from functors import partial
      
      def run_test_function(x, fun_arg2, fun_arg3, fun_arg4):
          # your code here
          ...
      
      process_func = partial(run_test_function, fun_arg2=arg2, fun_arg3=arg3, fun_arg4=arg4)
      

Putting this together:

from multiprocessing import Pool
from functools import partial

def run_test_function(x, fun_arg2, fun_arg3, fun_arg4):
    # this is an example
    print x, fun_arg2, fun_arg3, fun_arg4

if __name__ == "__main__":
    arg1 = 1,2,3,4
    arg2 = "hello"
    arg3 = "world"
    arg4 = "!"

    process_func = partial(run_test_function, fun_arg2=arg2, fun_arg3=arg3, fun_arg4=arg4)

    my_pool = Pool(4)
    my_pool.map(process_func, arg1)

Output:

~/test $ python2.7 so10.py
1 hello world !
2 hello world !
3 hello world !
4 hello world !
ForceBru
  • 43,482
  • 10
  • 63
  • 98
  • Thank you, it worked for me. What is the range of processors we can give? On what factor this value depends as you have given 4? – Vanshika Aug 17 '21 at 12:51
  • If your workloads are CPU-intensive (which is what the `multiprocessing` module is used for, as opposed to the `threading` module), it makes sense to create one process per CPU core. I know my CPU has 4 cores, so I created 4 processes. `Pool` [can determine the number of cores automatically](https://docs.python.org/3/library/multiprocessing.html#multiprocessing.pool.Pool), so you can just use `Pool()` without any arguments – ForceBru Aug 17 '21 at 14:20
  • After the execution of script, script worked fine but cli is getting hung, it went unresponsive. – Vanshika Aug 19 '21 at 09:59
  • @Vanshika, what's the script? The one in my answer? – ForceBru Aug 19 '21 at 11:12
  • Yeah, this is only the example I have used in my script. Moreover output isn't formatted, it is like you getting 1 hello world !, but it should be like 1 \nhello \nworld \n! – Vanshika Aug 19 '21 at 12:18
  • @Vanshika, not sure what the issue might be - everything works fine for me... – ForceBru Aug 19 '21 at 12:22
  • Okay, can you provide your inputs on why cli is getting hung after successful execution of script. – Vanshika Aug 19 '21 at 12:41
  • @Vanshika, again, not sure why this could be happening. You can always post a new question about this, though – ForceBru Aug 19 '21 at 13:23