Python 尝试并行化Sage代码会使用@parallel decorator或multiprocessing.Pool创建“thread\u suspend failed”和“Unhandled SIGABRT”错误

Python 尝试并行化Sage代码会使用@parallel decorator或multiprocessing.Pool创建“thread\u suspend failed”和“Unhandled SIGABRT”错误,python,multiprocessing,sage,Python,Multiprocessing,Sage,我有一些Sage代码,我正在尝试并行化,但遇到了线程挂起失败和未处理的SIGABRT错误的问题。我曾尝试过使用Python的multiprocessing.Pool类,但后来按照kcrisman的建议修改为使用Sage的@parallel,但无论我使用哪个类,都会出现相同的错误 我似乎无法创建一个最小的工作示例来重现这些错误,因此下面是我的代码的相关片段: @parallel def calculate_translation(direction, interval, tr): g =

我有一些Sage代码,我正在尝试并行化,但遇到了线程挂起失败和未处理的SIGABRT错误的问题。我曾尝试过使用Python的multiprocessing.Pool类,但后来按照kcrisman的建议修改为使用Sage的@parallel,但无论我使用哪个类,都会出现相同的错误

我似乎无法创建一个最小的工作示例来重现这些错误,因此下面是我的代码的相关片段:

@parallel
def calculate_translation(direction, interval, tr):
    g = Graphics()
    translations = {}


    discontinuities = tr.intervals[interval]
    num_discontinuities = len(discontinuities)


    (left_lbl, left_pt) = tr.interval_to_surface(interval, discontinuities[0])
    left_offset = tr.T.offsets[left_lbl]
    g += circle((left_offset[0] + left_pt[0], left_offset[1] + left_pt[1]),
                0.05, color='purple', fill=true)

    for i in xrange(1, num_discontinuities):
        (right_lbl, right_pt) = tr.interval_to_surface(interval, discontinuities[i])
        right_offset = tr.T.offsets[right_lbl]
        g += circle((right_offset[0] + right_pt[0], right_offset[1] + right_pt[1]),
                    0.05, color='purple', fill=true)

        # Determine the midpoint of the interval, then find
        # the corresponding point on the surface.
        mid_pt = (discontinuities[i-1] + discontinuities[i]) / 2
        (sq_lbl, pt0) = tr.interval_to_surface(interval, mid_pt, top_square = true)
        square = tr.T.surface.squares[sq_lbl]
        (x, y) = pt0

        # Determine where the corresponding square sits in the
        # picture.  Draw a red circle at the midpoint, where
        # our geodesic starts.
        (x0, y0) = tr.T.offsets[sq_lbl]
        g += circle((x0 + x, y0 + y), 0.05, color='red', fill=true)

        while true:
            # We are starting from init_square
            init_square = square.name

            # Get the coordinates (inside init_square) of our starting point.
            (x0, y0) = pt0

            # Get the coordinates (inside init_square) of the terminal point,
            # before entering the next square, and also record the new square.
            (x1, y1, next_square) = square.nextpt(pt0, direction)

            # Determine the offsets of the square (for drawing)
            (x_offset, y_offset) = tr.T.offsets[init_square]


            # Draw the piece of the geodesic inside of init_square
            g += line([(x0 + x_offset, y0 + y_offset),
                       (x1 + x_offset, y1 + y_offset)],
                      color='blue')

            if y1 == 1:
                # If we hit the top of init_square, check to
                # see if we've received one of the intervals.

                if tr.bottom_squares.count(init_square) > 0:
                    # bottom_squares records the squares, in
                    # the lower copies of the table, whose
                    # upper edge lies on an interval.  If
                    # we've started from such a square and hit
                    # its top edge, then we've returned to our
                    # interval.
                    terminal_square = init_square
                    (x_terminal, y_terminal) = (x1, y1)
                    break

                elif tr.top_squares.count(next_square.name) > 0:
                    # If the next square we would move
                    # into lives above the interval, then
                    # stop.  We need to reset the point so
                    # that we can use interval_to_surface
                    # later.
                    terminal_square = next_square.name
                    pt0 = TReturn.reset_point((x1, y1), direction)
                    (x_terminal, y_terminal) = pt0
                    break

            # If we did not yet hit one of our intervals,
            # rinse and repeat.
            pt0 = TReturn.reset_point((x1, y1), direction)
            square = next_square

        # Out of while loop, still in for loop.
        # have terminal_square, and (x_terminal, y_terminal) point
        (image_interval, image_pt) = tr.surface_to_interval(terminal_square,
                                                            (x_terminal, y_terminal))


        # Add image point to the graph.
        (x_offset, y_offset) = tr.T.offsets[terminal_square]
        g += circle((x_offset + x_terminal, y_offset + y_terminal), 0.05,
                    color='orange', fill=true)

        distance_to_left = mid_pt - discontinuities[i-1]
        translation = image_pt - distance_to_left
        translation = translation.full_simplify()

        translations[i] = (image_interval, translation)

    return (g, interval, translations)

class TReturn:
    # Other methods are defined, but not relevant.

    def parallel_calculate_translations(self):        
        graphic = Graphics()


        job_args = [(self.angle, key, self) for key in self.intervals.keys()]
        results = [x[1] for x in calculate_translation(job_args)]

        ## I tried using multiprocessing.Pool as well, but the same errors occurred. 
        # pool = Pool(2)        
        # results = pool.map(calculate_translation_helper, job_args)
        # pool.close()
        # pool.join()


        for i in xrange(0, len(results)):
            (g, interval, translation) = results[i]
            graphic += g
            self.translations[interval] = translation

        return graphic
运行代码时,将打印以下内容:

thread_suspend failed
Traceback (most recent call last):
  File "TReturn.py", line 1234, in <module>
tr = TReturn(_sage_const_2 , _sage_const_0p2354 , parallelize =  true)
  File "TReturn.py", line 306, in __init__
    self.calculate_instance_variables(generations, angle, parallelize)
  File "TReturn.py", line 517, in calculate_instance_variables
    self.iet_trajectories = self.parallel_calculate_translations()
  File "TReturn.py", line 954, in parallel_calculate_translations
    results = pool.map(calculate_translation_helper, job_args)
  File "/Applications/Sage-6.3.app/Contents/Resources/sage/local/lib/python/multiprocessing/pool.py", line 251, in map

仅供参考,您使用的不是Sage的东西,而是?此外,即使您可以将实际代码发布到某个代码片段站点,这也会对人们有所帮助;这似乎不太可能是一个纯粹的Python bug,而是您正在使用的任何Sage代码都被要求做太多的事情……感谢您的评论;实际上我完全忘记了@parallel decorator。但是,修改代码以使用它仍然会产生相同的错误。现在提供了一个代码片段。
thread_suspend failed
------------------------------------------------------------------------
Unhandled SIGABRT: An abort() occurred in Sage.
This probably occurred because a *compiled* component of Sage has a bug
in it and is not properly wrapped with sig_on(), sig_off().
Sage will now terminate.
------------------------------------------------------------------------