U
    ;rc~                     @   sd  d dgZ ddlZddlZddlZddlZddlZddlZddlZddlZddlm	Z	 ddl
mZ ddl
mZmZ ddlmZ d	Zd
ZdZdZe Zdd Zdd ZG dd deZG dd dZdd ZG dd deZd+ddZdd ZG dd  d eZ G d!d  d e!Z"G d"d# d#e!Z#e#Z$G d$d% d%e#Z%G d&d' d'e!Z&G d(d) d)e&Z'G d*d de"Z(dS ),Pool
ThreadPool    N)Empty   )util)get_contextTimeoutError)waitINITRUNCLOSE	TERMINATEc                 C   s   t t|  S N)listmapargs r   */usr/lib/python3.8/multiprocessing/pool.pymapstar/   s    r   c                 C   s   t t| d | d S )Nr   r   )r   	itertoolsstarmapr   r   r   r   starmapstar2   s    r   c                   @   s   e Zd Zdd Zdd ZdS )RemoteTracebackc                 C   s
   || _ d S r   tb)selfr   r   r   r   __init__:   s    zRemoteTraceback.__init__c                 C   s   | j S r   r   r   r   r   r   __str__<   s    zRemoteTraceback.__str__N)__name__
__module____qualname__r   r   r   r   r   r   r   9   s   r   c                   @   s   e Zd Zdd Zdd ZdS )ExceptionWithTracebackc                 C   s0   t t|||}d|}|| _d| | _d S )N z

"""
%s""")	tracebackformat_exceptiontypejoinexcr   )r   r)   r   r   r   r   r   @   s    
zExceptionWithTraceback.__init__c                 C   s   t | j| jffS r   )rebuild_excr)   r   r   r   r   r   
__reduce__E   s    z!ExceptionWithTraceback.__reduce__N)r    r!   r"   r   r+   r   r   r   r   r#   ?   s   r#   c                 C   s   t || _| S r   )r   	__cause__)r)   r   r   r   r   r*   H   s    
r*   c                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )MaybeEncodingErrorzVWraps possible unpickleable errors, so they can be
    safely sent through the socket.c                    s.   t || _t || _tt| | j| j d S r   )reprr)   valuesuperr-   r   )r   r)   r/   	__class__r   r   r   T   s    

zMaybeEncodingError.__init__c                 C   s   d| j | jf S )Nz(Error sending result: '%s'. Reason: '%s')r/   r)   r   r   r   r   r   Y   s    zMaybeEncodingError.__str__c                 C   s   d| j j| f S )Nz<%s: %s>)r2   r    r   r   r   r   __repr__]   s    zMaybeEncodingError.__repr__)r    r!   r"   __doc__r   r   r3   __classcell__r   r   r1   r   r-   P   s   r-   r   Fc              
   C   s  |d k	r(t |tr|dks(td||j}| j}t| drR| j  |j	  |d k	rb||  d}|d ks~|r||k rz
| }	W n( t
tfk
r   td Y qY nX |	d krtd q|	\}
}}}}zd|||f}W nH tk
r0 } z(|r|tk	rt||j}d|f}W 5 d }~X Y nX z||
||f W nR tk
r } z2t||d }td	|  ||
|d|ff W 5 d }~X Y nX d  }	 }
 } } }}|d7 }qftd
|  d S )Nr   zMaxtasks {!r} is not valid_writerr   z)worker got EOFError or OSError -- exitingzworker got sentinel -- exitingTFz0Possible encoding error while sending result: %szworker exiting after %d tasks)
isinstanceintAssertionErrorformatputgethasattrr6   close_readerEOFErrorOSErrorr   debug	Exception_helper_reraises_exceptionr#   __traceback__r-   )inqueueoutqueueinitializerinitargsZmaxtaskswrap_exceptionr;   r<   Z	completedtaskjobifuncr   kwdsresultewrappedr   r   r   workera   sN    





$
rS   c                 C   s   | dS )z@Pickle-able helper function for use by _guarded_task_generation.Nr   )Zexr   r   r   rD      s    rD   c                       s2   e Zd ZdZdd fdd
Z fddZ  ZS )
_PoolCachez
    Class that implements a cache for the Pool class that will notify
    the pool management threads every time the cache is emptied. The
    notification is done by the use of a queue that is provided when
    instantiating the cache.
    Nnotifierc                  s   || _ t j|| d S r   )rV   r0   r   )r   rV   r   rO   r1   r   r   r      s    z_PoolCache.__init__c                    s    t  | | s| jd  d S r   )r0   __delitem__rV   r;   )r   itemr1   r   r   rW      s    z_PoolCache.__delitem__)r    r!   r"   r4   r   rW   r5   r   r   r1   r   rT      s   rT   c                   @   s  e Zd ZdZdZedd ZdLddZej	e
fd	d
Zdd Zdd Zedd Zedd Zdd Zedd Zedd Zdd Zdd Zdi fddZdMdd ZdNd!d"ZdOd#d$Zd%d& ZdPd(d)ZdQd*d+Zdi ddfd,d-ZdRd.d/ZdSd0d1ZedTd2d3Ze d4d5 Z!ed6d7 Z"ed8d9 Z#ed:d; Z$d<d= Z%d>d? Z&d@dA Z'dBdC Z(edDdE Z)e dFdG Z*dHdI Z+dJdK Z,dS )Ur   zS
    Class which supports an async version of applying functions to arguments.
    Tc                 O   s   | j ||S r   Process)ctxr   rO   r   r   r   rZ      s    zPool.ProcessNr   c                 C   s  g | _ t| _|pt | _|   t | _| j | _	t
| j	d| _|| _|| _|| _|d krjt phd}|dk rztd|d k	rt|std|| _z|   W nH tk
r   | j D ]}|jd kr|  q| j D ]}|  q؂ Y nX |  }tjtj| j| j| j| j| j| j | j | j!| j| j| j| j"|| j	fd| _#d| j#_$t%| j#_| j#&  tjtj'| j| j(| j!| j | jfd| _)d| j)_$t%| j)_| j)&  tjtj*| j!| j+| jfd| _,d| j,_$t%| j,_| j,&  t-j.| | j/| j| j | j!| j | j	| j#| j)| j,| jf	dd| _0t%| _d S )	NrU   r   z&Number of processes must be at least 1zinitializer must be a callabletargetr   T   )r   Zexitpriority)1_poolr
   _stater   _ctx_setup_queuesqueueSimpleQueue
_taskqueue_change_notifierrT   _cache_maxtasksperchild_initializer	_initargsos	cpu_count
ValueErrorcallable	TypeError
_processes_repopulate_poolrC   exitcode	terminater(   _get_sentinels	threadingZThreadr   _handle_workersrZ   _inqueue	_outqueue_wrap_exception_worker_handlerdaemonr   start_handle_tasks
_quick_put_task_handler_handle_results
_quick_get_result_handlerr   ZFinalize_terminate_pool
_terminate)r   	processesrH   rI   maxtasksperchildcontextp	sentinelsr   r   r   r      s    





       
 

    zPool.__init__c                 C   s>   | j |kr:|d| t| d t| dd d k	r:| jd  d S )Nz&unclosed running multiprocessing pool )sourcerf   )r`   ResourceWarninggetattrrf   r;   )r   Z_warnr   r   r   r   __del__  s    

 zPool.__del__c              	   C   s0   | j }d|j d|j d| j dt| j d	S )N<.z state=z pool_size=>)r2   r!   r"   r`   lenr_   )r   clsr   r   r   r3     s    zPool.__repr__c                 C   s   | j jg}| jjg}||S r   )rx   r?   rf   )r   Ztask_queue_sentinelsZself_notifier_sentinelsr   r   r   rt     s    

zPool._get_sentinelsc                 C   s   dd | D S )Nc                 S   s   g | ]}t |d r|jqS )sentinel)r=   r   ).0rS   r   r   r   
<listcomp>  s    
z.Pool._get_worker_sentinels.<locals>.<listcomp>r   Zworkersr   r   r   _get_worker_sentinels  s    zPool._get_worker_sentinelsc                 C   sP   d}t tt| D ]6}| | }|jdk	rtd|  |  d}| |= q|S )zCleanup after any worker processes which have exited due to reaching
        their specified lifetime.  Returns True if any workers were cleaned up.
        FNcleaning up worker %dT)reversedranger   rr   r   rB   r(   )poolZcleanedrM   rS   r   r   r   _join_exited_workers  s    
zPool._join_exited_workersc                 C   s0   |  | j| j| j| j| j| j| j| j| j	| j

S r   )_repopulate_pool_staticra   rZ   rp   r_   rw   rx   ri   rj   rh   ry   r   r   r   r   rq   .  s      zPool._repopulate_poolc
              
   C   sf   t |t| D ]P}
|| t||||||	fd}|jdd|_d|_|  || t	d qdS )zBring the number of pool processes up to the specified number,
        for use after reaping workers which have exited.
        r\   rZ   Z
PoolWorkerTzadded workerN)
r   r   rS   namereplacer{   r|   appendr   rB   )r[   rZ   r   r   rF   rG   rH   rI   r   rJ   rM   wr   r   r   r   7  s     
zPool._repopulate_pool_staticc
           
      C   s*   t |r&t | |||||||||	
 dS )zEClean up any exited workers and start replacements for them.
        N)r   r   r   )
r[   rZ   r   r   rF   rG   rH   rI   r   rJ   r   r   r   _maintain_poolJ  s    
   zPool._maintain_poolc                 C   s4   | j  | _| j  | _| jjj| _| jjj| _	d S r   )
ra   rd   rw   rx   r6   sendr~   r?   recvr   r   r   r   r   rb   V  s    zPool._setup_queuesc                 C   s   | j tkrtdd S )NzPool not running)r`   r   rm   r   r   r   r   _check_running\  s    
zPool._check_runningc                 C   s   |  ||| S )zT
        Equivalent of `func(*args, **kwds)`.
        Pool must be running.
        )apply_asyncr<   )r   rN   r   rO   r   r   r   apply`  s    z
Pool.applyc                 C   s   |  ||t| S )zx
        Apply `func` to each element in `iterable`, collecting the results
        in a list that is returned.
        )
_map_asyncr   r<   r   rN   iterable	chunksizer   r   r   r   g  s    zPool.mapc                 C   s   |  ||t| S )z
        Like `map()` method but the elements of the `iterable` are expected to
        be iterables as well and will be unpacked as arguments. Hence
        `func` and (a, b) becomes func(a, b).
        )r   r   r<   r   r   r   r   r   n  s    zPool.starmapc                 C   s   |  ||t|||S )z=
        Asynchronous version of `starmap()` method.
        )r   r   r   rN   r   r   callbackerror_callbackr   r   r   starmap_asyncv  s     zPool.starmap_asyncc              
   c   sj   z,d}t |D ]\}}||||fi fV  qW n8 tk
rd } z||d t|fi fV  W 5 d}~X Y nX dS )zProvides a generator of tasks for imap and imap_unordered with
        appropriate handling for iterables which throw exceptions during
        iteration.r   N)	enumeraterC   rD   )r   Z
result_jobrN   r   rM   xrQ   r   r   r   _guarded_task_generation~  s    zPool._guarded_task_generationr   c                 C   s   |    |dkr:t| }| j| |j|||jf |S |dk rPtd|t	
|||}t| }| j| |jt||jf dd |D S dS )zP
        Equivalent of `map()` -- can be MUCH slower than `Pool.map()`.
        r   zChunksize must be 1+, not {0:n}c                 s   s   | ]}|D ]
}|V  q
qd S r   r   r   chunkrX   r   r   r   	<genexpr>  s       zPool.imap.<locals>.<genexpr>N)r   IMapIteratorre   r;   r   _job_set_lengthrm   r:   r   
_get_tasksr   r   rN   r   r   rP   task_batchesr   r   r   imap  s4    z	Pool.imapc                 C   s   |    |dkr:t| }| j| |j|||jf |S |dk rPtd|t	
|||}t| }| j| |jt||jf dd |D S dS )zL
        Like `imap()` method but ordering of results is arbitrary.
        r   zChunksize must be 1+, not {0!r}c                 s   s   | ]}|D ]
}|V  q
qd S r   r   r   r   r   r   r     s       z&Pool.imap_unordered.<locals>.<genexpr>N)r   IMapUnorderedIteratorre   r;   r   r   r   rm   r:   r   r   r   r   r   r   r   imap_unordered  s0    zPool.imap_unorderedc                 C   s6   |    t| ||}| j|jd|||fgdf |S )z;
        Asynchronous version of `apply()` method.
        r   N)r   ApplyResultre   r;   r   )r   rN   r   rO   r   r   rP   r   r   r   r     s    zPool.apply_asyncc                 C   s   |  ||t|||S )z9
        Asynchronous version of `map()` method.
        )r   r   r   r   r   r   	map_async  s    zPool.map_asyncc           
      C   s   |    t|dst|}|dkrJtt|t| jd \}}|rJ|d7 }t|dkrZd}t|||}t| |t|||d}	| j	
| |	j||df |	S )zY
        Helper function to implement map, starmap and their async counterparts.
        __len__N   r   r   r   )r   r=   r   divmodr   r_   r   r   	MapResultre   r;   r   r   )
r   rN   r   Zmapperr   r   r   Zextrar   rP   r   r   r   r     s,    
zPool._map_asyncc                 C   s"   t | |d | s|  qd S )N)timeout)r	   emptyr<   )r   change_notifierr   r   r   r   _wait_for_updates  s    zPool._wait_for_updatesc                 C   sp   t  }|jtks |rX|jtkrX| |||||||	|
||
 | ||}| || q|d  t	
d d S )Nzworker handler exiting)ru   current_threadr`   r   r   r   r   r   r;   r   rB   )r   cache	taskqueuer[   rZ   r   r   rF   rG   rH   rI   r   rJ   r   r   threadZcurrent_sentinelsr   r   r   rv     s       
zPool._handle_workersc                 C   sp  t  }t| jd D ]\}}d }z|D ]}|jtkrBtd  qz|| W q& tk
r }
 zB|d d \}	}z||	 	|d|
f W n t
k
r   Y nX W 5 d }
~
X Y q&X q&|rtd |r|d nd}||d  W qW 
 q
W 5 d  } }}	X qtd z6td |d  td	 |D ]}|d  q.W n  tk
r`   td
 Y nX td d S )Nz'task handler found thread._state != RUN   Fzdoing set_length()r   r   ztask handler got sentinelz/task handler sending sentinel to result handlerz(task handler sending sentinel to workersz/task handler got OSError when sending sentinelsztask handler exiting)ru   r   iterr<   r`   r   r   rB   rC   _setKeyErrorr;   rA   )r   r;   rG   r   r   r   ZtaskseqZ
set_lengthrK   rL   rQ   idxr   r   r   r   r}     sB    






zPool._handle_tasksc              	   C   s  t  }z
| }W n$ ttfk
r6   td Y d S X |jtkr`|jtksTt	dtd q|d krttd q|\}}}z|| 
|| W n tk
r   Y nX d  } }}q|rR|jtkrRz
| }W n$ ttfk
r   td Y d S X |d krtd q|\}}}z|| 
|| W n tk
rB   Y nX d  } }}qt| drtd z,tdD ]}| j s q|  qrW n ttfk
r   Y nX td	t||j d S )
Nz.result handler got EOFError/OSError -- exitingzThread not in TERMINATEz,result handler found thread._state=TERMINATEzresult handler got sentinelz&result handler ignoring extra sentinelr?   z"ensuring that outqueue is not full
   z7result handler exiting: len(cache)=%s, thread._state=%s)ru   r   rA   r@   r   rB   r`   r   r   r9   r   r   r=   r   r?   pollr   )rG   r<   r   r   rK   rL   rM   objr   r   r   r   :  s^    











 zPool._handle_resultsc                 c   s0   t |}tt||}|s d S | |fV  qd S r   )r   tupler   islice)rN   itsizer   r   r   r   r   v  s
    zPool._get_tasksc                 C   s   t dd S )Nz:pool objects cannot be passed between processes or pickled)NotImplementedErrorr   r   r   r   r+     s    zPool.__reduce__c                 C   s2   t d | jtkr.t| _t| j_| jd  d S )Nzclosing pool)r   rB   r`   r   r   rz   rf   r;   r   r   r   r   r>     s
    

z
Pool.closec                 C   s   t d t| _|   d S )Nzterminating pool)r   rB   r   r`   r   r   r   r   r   rs     s    
zPool.terminatec                 C   sj   t d | jtkrtdn| jttfkr4td| j  | j	  | j
  | jD ]}|  qXd S )Nzjoining poolzPool is still runningzIn unknown state)r   rB   r`   r   rm   r   r   rz   r(   r   r   r_   )r   r   r   r   r   r(     s    






z	Pool.joinc                 C   s@   t d | j  | r<| j r<| j  t	d qd S )Nz7removing tasks from inqueue until task handler finishedr   )
r   rB   Z_rlockacquireis_aliver?   r   r   timesleep)rF   task_handlerr   r   r   r   _help_stuff_finish  s
    


zPool._help_stuff_finishc
                 C   sX  t d t|_|d  t|_t d | ||t| | sXt|	dkrXtdt|_|d  |d  t d t	
 |k	r|  |rt|d drt d |D ]}
|
jd kr|
  qt d t	
 |k	r|  t d	 t	
 |k	r|  |rTt|d drTt d
 |D ](}
|
 r*t d|
j  |
  q*d S )Nzfinalizing poolz&helping task handler/workers to finishr   z.Cannot have cache with result_hander not alivezjoining worker handlerrs   zterminating workerszjoining task handlerzjoining result handlerzjoining pool workersr   )r   rB   r   r`   r;   r   r   r   r9   ru   r   r(   r=   rr   rs   pid)r   r   rF   rG   r   r   Zworker_handlerr   Zresult_handlerr   r   r   r   r   r     sB    












zPool._terminate_poolc                 C   s   |    | S r   )r   r   r   r   r   	__enter__  s    zPool.__enter__c                 C   s   |    d S r   )rs   )r   exc_typeZexc_valZexc_tbr   r   r   __exit__  s    zPool.__exit__)NNr   NN)N)N)NNN)r   )r   )NNN)NNN)N)-r    r!   r"   r4   ry   staticmethodrZ   r   warningswarnr   r   r3   rt   r   r   rq   r   r   rb   r   r   r   r   r   r   r   r   r   r   r   r   classmethodrv   r}   r   r   r+   r>   rs   r(   r   r   r   r   r   r   r   r   r      sx   
    
P

	



  




  
  


-
;


5c                   @   s@   e Zd Zdd Zdd Zdd Zddd	Zdd
dZdd ZdS )r   c                 C   s>   || _ t | _tt| _|j| _|| _|| _	| | j| j< d S r   )
r_   ru   ZEvent_eventnextjob_counterr   rg   	_callback_error_callback)r   r   r   r   r   r   r   r     s    

zApplyResult.__init__c                 C   s
   | j  S r   )r   Zis_setr   r   r   r   ready  s    zApplyResult.readyc                 C   s   |   std| | jS )Nz{0!r} not ready)r   rm   r:   _successr   r   r   r   
successful  s    zApplyResult.successfulNc                 C   s   | j | d S r   )r   r	   r   r   r   r   r   r	     s    zApplyResult.waitc                 C   s,   |  | |  st| jr"| jS | jd S r   )r	   r   r   r   _valuer   r   r   r   r<     s    
zApplyResult.getc                 C   sZ   |\| _ | _| jr$| j r$| | j | jr<| j s<| | j | j  | j| j= d | _d S r   )	r   r   r   r   r   setrg   r   r_   r   rM   r   r   r   r   r     s    

zApplyResult._set)N)N)	r    r!   r"   r   r   r   r	   r<   r   r   r   r   r   r     s   	

	r   c                   @   s   e Zd Zdd Zdd ZdS )r   c                 C   sh   t j| |||d d| _d g| | _|| _|dkrNd| _| j  | j| j	= n|| t
||  | _d S )Nr   Tr   )r   r   r   r   
_chunksize_number_leftr   r   rg   r   bool)r   r   r   lengthr   r   r   r   r   r     s    

zMapResult.__init__c                 C   s   |  j d8  _ |\}}|rv| jrv|| j|| j |d | j < | j dkr| jrZ| | j | j| j= | j  d | _	nL|s| jrd| _|| _| j dkr| j
r| 
| j | j| j= | j  d | _	d S )Nr   r   F)r   r   r   r   r   rg   r   r   r   r_   r   )r   rM   Zsuccess_resultsuccessrP   r   r   r   r   $  s&    







zMapResult._setN)r    r!   r"   r   r   r   r   r   r   r     s   r   c                   @   s:   e Zd Zdd Zdd ZdddZeZdd	 Zd
d ZdS )r   c                 C   sT   || _ tt | _tt| _|j| _t	
 | _d| _d | _i | _| | j| j< d S )Nr   )r_   ru   Z	ConditionZLock_condr   r   r   rg   collectionsdeque_items_index_length	_unsorted)r   r   r   r   r   r   B  s    

zIMapIterator.__init__c                 C   s   | S r   r   r   r   r   r   __iter__M  s    zIMapIterator.__iter__Nc                 C   s   | j  z| j }W nz tk
r   | j| jkr>d | _td | j | z| j }W n2 tk
r   | j| jkrd | _td t	d Y nX Y nX W 5 Q R X |\}}|r|S |d S r   )
r   r   popleft
IndexErrorr   r   r_   StopIterationr	   r   )r   r   rX   r   r/   r   r   r   r   P  s&    zIMapIterator.nextc              	   C   s   | j  | j|krn| j| |  jd7  _| j| jkrb| j| j}| j| |  jd7  _q,| j   n
|| j|< | j| jkr| j| j	= d | _
W 5 Q R X d S Nr   )r   r   r   r   r  popnotifyr   rg   r   r_   r   r   r   r   r   h  s    


zIMapIterator._setc              	   C   sB   | j 2 || _| j| jkr4| j   | j| j= d | _W 5 Q R X d S r   )r   r   r   r  rg   r   r_   )r   r   r   r   r   r   y  s    

zIMapIterator._set_length)N)	r    r!   r"   r   r  r   __next__r   r   r   r   r   r   r   @  s   
r   c                   @   s   e Zd Zdd ZdS )r   c              	   C   sV   | j F | j| |  jd7  _| j   | j| jkrH| j| j= d | _W 5 Q R X d S r  )	r   r   r   r   r  r   rg   r   r_   r   r   r   r   r     s    

zIMapUnorderedIterator._setN)r    r!   r"   r   r   r   r   r   r     s   r   c                   @   sV   e Zd ZdZedd ZdddZdd	 Zd
d Zedd Z	edd Z
dd ZdS )r   Fc                 O   s   ddl m} |||S )Nr   rY   )ZdummyrZ   )r[   r   rO   rZ   r   r   r   rZ     s    zThreadPool.ProcessNr   c                 C   s   t | ||| d S r   )r   r   )r   r   rH   rI   r   r   r   r     s    zThreadPool.__init__c                 C   s,   t  | _t  | _| jj| _| jj| _d S r   )rc   rd   rw   rx   r;   r~   r<   r   r   r   r   r   rb     s    


zThreadPool._setup_queuesc                 C   s
   | j jgS r   )rf   r?   r   r   r   r   rt     s    zThreadPool._get_sentinelsc                 C   s   g S r   r   r   r   r   r   r     s    z ThreadPool._get_worker_sentinelsc                 C   sF   z| j dd qW n tjk
r(   Y nX t|D ]}| d  q2d S )NF)block)r<   rc   r   r   r;   )rF   r   r   rM   r   r   r   r     s    zThreadPool._help_stuff_finishc                 C   s   t | d S r   )r   r   )r   r   r   r   r   r   r   r     s    zThreadPool._wait_for_updates)NNr   )r    r!   r"   ry   r   rZ   r   rb   rt   r   r   r   r   r   r   r   r     s   




)Nr   NF))__all__r   r   rk   rc   ru   r   r%   r   r   r$   r   r   r   Z
connectionr	   r
   r   r   r   countr   r   r   rC   r   r#   r*   r-   rS   rD   dictrT   objectr   r   ZAsyncResultr   r   r   r   r   r   r   r   <module>
   sN   	  
-    =)+E