7
votes

Connexion "Demandes Python" de la fermeture d'un autre fil

Pour fermer l'application dans les meilleurs délais, puis-je interrompre les demandes de requête.Post d'appel d'un autre thread et de terminer la connexion immédiatement?

J'ai joué avec des adaptateurs, mais pas de chance jusqu'à présent: xxx


0 commentaires

3 Réponses :


0
votes

Donc, si vous suivez dans la coque interactive, vous verrez que la fermeture des adaptateurs ne semble pas faire ce que vous recherchez.

This will not affect in-flight connections, but they will not be
re-used after completion.


2 commentaires

Oui, malheureusement, les demandes ne sont pas conçues de cette façon, je suppose que de petites demandes HTTP étaient l'objectif principal. J'utilise pour une application de bureau et le client doit être interrompu.


Vous pourrez peut-être creuser profondément dans Urllib3 et fermer la prise de force, mais Urllib3 est assise sur HTTPLIB et je ne sais pas si cela est même possible là-bas. Si vous souhaitez que votre contrôle grainé fin, vous pouvez construire vous-même la requête entière (et analyser la réponse) à l'aide des prises brutes. Lorsque l'utilisateur veut annuler quelque chose, vous fermez simplement la prise. C'est beaucoup de travail cependant.



2
votes

J'ai trouvé un moyen, voici comment interrompre la connexion xxx

Cependant, c'est un piratage et je n'aime pas cela, les membres privés peuvent changer à l'avenir, je retourne à urllib2


2 commentaires

Ces jours-ci, il y a aussi Response.Close , qui semble faire beaucoup la même chose.


Cette méthode est utile lorsque votre thread est bloqué à la lecture du flux, et vous souhaitez annuler la lecture. Il semble qu'il y a quelques secondes de quelques secondes après avoir appelé à proximité avant l'abandon du lecteur.



4
votes

La bonne façon de le faire est d'utiliser le message passant dans l'autre thread. Nous pouvons faire une version médiocre de celle-ci en utilisant une variable globale partagée. Par exemple, vous pouvez essayer d'exécuter ce script:

#!/usr/bin/env python
# A test script to verify that you can abort streaming downloads of large
# files.
import threading
import time
import requests

stop_download = False

def download(url):
    r = requests.get(url, stream=True)
    data = ''
    content_gen = r.iter_content()

    while (stop_download == False):
        try:
            data = r.iter_content(1024)
        except StopIteration:
            break

    if (stop_download == True):
        print 'Killed from other thread!'
        r.close()

if __name__ == '__main__':
    t = threading.Thread(target=download, 
                         args=('http://ftp.freebsd.org/pub/FreeBSD/ISO-IMAGES-amd64/9.1/FreeBSD-9.1-RELEASE-amd64-dvd1.iso',)
                        ).start()
    time.sleep(5)
    stop_download = True
    time.sleep(5) # Just to make sure you believe that the message actually stopped the other thread.


4 commentaires

Vous pouvez également utiliser une très petite taille de contenu pour obtenir un contrôle plus fin lors de son annulation. Et votre content_gen = r.iter_content () la ligne est inutile;)


iter_content () renvoie un itérateur (ou générateur), vous devez donc vraiment faire quelque chose comme content_gen = r.iter_content (1024) suivi de plusieurs suivant (content_gen) .


@Lukasa, pouvez-vous me dire que lorsque la ligne r = demande.get (URL, flux = true) a été exécutée, les données de réponse seront-elles toutes téléchargées quelque part dans la RAM? Parce que je ne sais pas quand data = r.iter_content (1024) , où provient les données de 1024 octets. Je me demande que si tel est le cas, tuez la demande plus tard à aucune autre chose, car les données ont déjà été téléchargées (demandes / réponse sont terminées).


Non. Qu'est-ce que flux = true est que les demandes empêchent de tirer des données du système d'exploitation une fois qu'il a tous les en-têtes. Le reste des données est situé dans le tampon de prise OS, qui sera éventuellement ralenti et arrêté par TCP si vous ne le lisez pas. Jusqu'à ce que vous ayez itérale sur certaines données dans iter_Content, vous n'avez pas le reste des données en mémoire.