2017-09-28 10 views
0

Je veux utiliser multitraitement au générateur de rapports de vitesse pour chaque entrepriseurlopen de urllib2 seront bloc dans multitraitement

suivant est script de test:

from multiprocessing import Pool 
import os, time, random, json, urllib, urllib2, uuid 

def generate_report(url, cookie, company_id, period, remark): 
    try: 
     start = time.time() 
     print('Run task %s (%s)... at: %s \n' % (company_id, os.getpid(), start)) 

     values = { 
      'companies': json.dumps([company_id]), 
      'month_year': period, 
      'remark': remark 
     } 

     data = urllib.urlencode(values) 

     headers = { 
      'Cookie': cookie 
     } 
     url = "%s?pid=%s&uuid=%s" % (url, os.getpid(), uuid.uuid4().get_hex()) 
     request = urllib2.Request(url, data, headers) 
     response = urllib2.urlopen(request) 
     content = response.read() 
     end = time.time() 
     print 'Task %s runs %0.2f seconds, end at: %s \n' % (company_id, (end - start), end) 
     return content 
    except Exception as exc: 
     return exc.message 

if __name__=='__main__': 
    print 'Parent process %s.\n' % os.getpid() 
    p = Pool() 

    url = 'http://localhost/fee_calculate/generate-single' 
    cookie = 'xxx' 
    company_ids = [17,15,21,19] 
    period = '2017-08' 
    remark = 'test add remark from python script' 

    results = [p.apply_async(generate_report, args=(url,cookie,company_id,period,remark)) for company_id in company_ids] 
    for r in results: 
     print(r.get()) 

mais je reçois le résultat comme suit:

Run task 17 (15952)... at: 1506568581.98 
Run task 15 (17192)... at: 1506568581.99 
Run task 21 (18116)... at: 1506568582.01 
Run task 19 (1708)... at: 1506568582.05 

Task 17 runs 13.50 seconds, end at: 1506568595.48 

{"success":true,"info":"Successed!"} 
Task 15 runs 23.60 seconds, end at: 1506568605.59 

{"success":true,"info":"Successed!"} 
Task 21 runs 34.35 seconds, end at: 1506568616.36 

{"success":true,"info":"Successed!"} 
Task 19 runs 44.38 seconds, end at: 1506568626.44 

{"success":true,"info":"Successed!"} 

il semble que l'urllib2.urlopen (requête) a été bloquée, la demande n'a pas été envoyée parallèlement, mais de manière ordonnée.

Afin de tester multitraitement, le script fee_calculate/generate-simple a seulement suivant le code important:

sleep(10) 

s'il vous plaît me donner des conseils, merci.

PS: Plate-forme: Windows 10, python2.7, 4 CPU

+0

Combien de cœurs de processeur votre machine possède-t-elle? Essayez d'exécuter os.cpu_count() et voyez le résultat. – DBrowne

+0

Etes-vous sûr que ce temps devrait être moindre? Probablement générer des rapports prendre tout le temps? Vous pouvez essayer d'utiliser 'async' au lieu de' multiprocessing' – AndMar

+0

@DBrowne il y a quatre cpu, donc, je viens de fourche 4 sous-processus comme ceci: company_ids = [17,15,21,19] –

Répondre

1

Ce n'est pas une question multitraitement. Le multitraitement fonctionne comme il se doit, ce que vous pouvez voir en observant que toutes les tâches démarrent à peu près en même temps.

Le temps d'exécution de la tâche est presque entièrement dicté par le temps de réponse de votre point de terminaison local à http://localhost/fee_calculate/generate-single. Comment utilisez-vous ce serveur? Si vous observez les temps d'exécution pour chacun des rapports, vous remarquerez qu'ils augmentent par pas de ~ 10 secondes, ce qui est votre délai de traitement imposé artificiellement du côté serveur (sleep(10)).

Je suppose que votre serveur local est uniquement monothread et ne peut donc traiter qu'une seule requête à la fois. Cela signifie que chaque requête doit être complétée avant que la suivante ne soit traitée. Ainsi, lorsque vous effectuez plusieurs requêtes simultanées comme celle-ci, vous n'obtenez aucune diminution du temps de traitement.

+0

Au tout début, je soupçonne que le serveur local est aussi unique. J'ai donc vérifié XAMPP mpm_winnt_module, et ouvert http: // localhost/fee_calculate/generate-single dans plusieurs onglets sur Firefox. J'ai vérifié tous les en-têtes de réponse, ils retournent presque en même temps, ont seulement 1 ~ 2 seconde écart –

+0

Que se passe-t-il lorsque vous ouvrez plusieurs onglets dans Firefox en même temps? Est-ce que tous se terminent après 10 secondes? Ou prennent-ils plus de temps que cela? – DBrowne

+0

J'ai corrigé ce bug. Oui, ce n'est pas un problème de multi-traitement. Je pense que le bogue est le même cookie qui mène au verrouillage de la session en attente. l'application a été construite sur zend_framework. Merci beaucoup. –