Newsgroup: it.comp.lang.perl
Titolo: Supporto per i thread e per i socket

Salve,
sto scrivendo un news sucker per Linux simile a suck e a newsx, che
tra le altre cose deve poter scaricare news usando piu' thread in
parallelo.
Ho pensato di usare un linguaggio di scripting per impostare il
lavoro, ed in un secondo tempo decidero' se sara' il caso di farne una
traduzione in C++ per questioni di performance.
Visto che sono abbastanza pratico di Python, ho iniziato ad usare
questo linguaggio, ma mi sono reso conto che l'over-head che introduce
l'interprete e' un po' troppo grande, e probabilmente mi vedro'
costretto a fare la traduzione.
Percio' prima di continuare lo sviluppo usando Python vorrei
considerare qualche alternativa; AFAIK perl e' uno degli dei linguaggi
piu' prestanti per quanto riguarda la gestione di file di testo, ma
non so come vada con socket e threads. Qualcuno mi potrebbe dare
qualche indicazione a riguardo?
+++
Sarebbe veramente il massimo se qualche anima pia mi facesse un
piccolo script in perl che mi permettesse di valutarne concretamente
le prestazioni; ho isolato la parte critica del mio programma, ed in
sostanza e' sufficiente fare uno script che:
- si connetta ad un server news
- mandi il comando modereader
- si scarichi la lista dei message-id degli ultimi N messaggi usando il
  comando XHDR
- divida la lista in M parti
- lanci M thread, ciascuno dei quali si scarichi la sua parte degli
  articoli mettendoli in una directory
Riporto di seguito come si puo' implementare questo script in Python,
nel caso qualcuno conosca bene entrambi i linguaggi e possa farne una
traduzione:
---------------------------------- fetchnews.py -----------------------
#!/usr/bin/python
import os, nntplib, threading, tempfile, Queue
# numero di thread da usare
THREAD_NO = 3
# massimo numero di messaggi da scaricare
MSG_LIMIT = 100
def main ():
    # si connette al server e crea una lista di tuple (num, mid) dove
    # mid e' il message-ID di un articolo e num e' il suo numero sul
    # server
    server = nntplib.NNTP("localhost")
    resp = server.shortcmd("modereader")
    resp, count, first, last, name = server.group("comp.lang.python")
    resp, nums_mids = server.xhdr("message-id", "%s-%s" % (first, last))
    server.quit()
    # prende solo i `MSG_LIMIT' messaggi piu' recenti
    nums_mids = nums_mids[-MSG_LIMIT:]
    # spezza la lista dei messaggi in `THREAD_NO' parti
    chunks = splitseq(nums_mids, THREAD_NO)
    # lancia un thread per ogni lista di messaggi
    for i in xrange(THREAD_NO):
	d = threading.Thread(target=th_sucker, args=(chunks[i],))
	d.start()
# spezza una la sequenza `seq' in `divisor' parti
def splitseq(seq, divisor):
    length = len(seq)
    chunk = length / divisor
    splitted_seq = []
    start = 0
    while start < length:
	end = start + chunk
	splitted_seq.append(seq[start:end])
	start = end
    return splitted_seq
# funzione che implementa ciascun thread; `nums_mids' e' la lista di tuple
def th_sucker(nums_mids):
    # prende il nome del thread (solo per fare un po' d'output dopo)
    myname = threading.currentThread().getName()
    # imposta la directory dove mettere i messaggi
    tempfile.tempdir = "./spool"
    # apre una connessione con il server
    server = nntplib.NNTP("localhost")
    resp = server.shortcmd("modereader")
    # itera sulla lista di message-ids
    for num, mid in nums_mids:
	# scarica l'articolo
	resp, nr, id, lines = server.article(mid)
	# aggiunge i newline
	for i in xrange(len(lines)):
	    lines[i] = lines[i] + "\n"
	# crea un nuovo file
	filename = tempfile.mktemp()
	fd = open(filename, "w")
	# ci scrive dentro l'articolo
	fd.writelines(lines)
	# fa un po' di output
	print myname, "get one"
    # chiude la connessione
    server.quit()
if __name__=="__main__": main()
---------------------------------- fetchnews.py -----------------------
Ovviamente non posso promettere nulla in cambio del favore, se non la
mia gratitudine e un posto nel file di THANKS ;)
Ringrazio in anticipo,
-- 
Diego Dainese
-> Per le repliche elimina dal mio indirizzo le cifre e le `x'.
-> ATTENZIONE: se non ricevete risposta ad un messaggio che avete
   rivolto a me, probabilmente la colpa e' del server del mio ISP,
   quindi per favore fatemi un CC del messaggio in email, grazie.

 wrote:
: Percio' prima di continuare lo sviluppo usando Python vorrei
: considerare qualche alternativa; AFAIK perl e' uno degli dei linguaggi
: piu' prestanti per quanto riguarda la gestione di file di testo, ma
: non so come vada con socket e threads. Qualcuno mi potrebbe dare
: qualche indicazione a riguardo?
Mi sembra strano che il Python non sia abbastanza veloce con i socket:
di solito il collo di bottiglia e` in Internet o nella comunicazione tra
te e il provider (vai a piu` di 64k?), non nel linguaggio...
: Sarebbe veramente il massimo se qualche anima pia mi facesse un
: piccolo script in perl che mi permettesse di valutarne concretamente
: le prestazioni; ho isolato la parte critica del mio programma, ed in
: sostanza e' sufficiente fare uno script che:
Questo e` un pezzettino di codice per prelevare i subjects degli
articoli:
#!/usr/bin/perl
use Net::NNTP;
use Getopt::Std;
getopt('pu');
if(!defined $ARGV[0]){
	print "Uso: $0 [-pprimo] [-uultimo] nome_gruppo [server]\n";
	exit;
}
$ARGV[1] = 'localhost' if !defined $ARGV[1];
($c = new Net::NNTP($ARGV[1])) || die $!; # die on timeout
(($num_arts, $primo, $ultimo, $nome) = ($c->group($ARGV[0]))) || die $!;
$primo = $opt_p if defined $opt_p;
$ultimo = $opt_u if defined $opt_u;
$heads = $c->xhdr("Subject", $primo, $ultimo);
print "$ARGV[0]\n";
foreach $head (keys %$heads){
	print "$head $heads->{$head}\n";
}
-- 
Nando Santagata: Telemastica & infornatica
Key fingerprint = C2 D9 C0 8E D5 B7 04 97  AF E8 3F 3E AF 4E 7F 9E
finger nando (at) mail (dot) ipers (dot) net   for my PGP public key
Home: 
http://www.ipers.net/~nandos

 articoli:
[snip]
Grazie; l'ho addattato per fargli scaricare anche i messaggi e ho
misurato i tempi: purtroppo le prestazioni non sono molto migliori di
quelle di Python, quindi anche per il perl sarebbe necessaria una
traduzione.
Tra parentesi questo e' quasi un sollievo per me: almeno posso
continuare ad usare il linguaggio che preferisco senza timore di aver
scartato un alternativa piu' efficiente ;)
Ciao e grazie ancora,
