2011-04-27 4 views
2

En utilisant l'IRM Ruby 1.9 J'ai un code commeRuby Threading Will not changement de contexte

def foo() 
    puts "in foo" 
    loop do 
    puts "in foo loop" 
    end 
end 

def bar() 
    puts "in bar" 
    start_alsa_listener 
end 

foo_thread = Thread.new { foo } 
bar_thread = Thread.new { bar } 
foo_thread.join 
bar_thread.join 

start_alsa_listener est un appel bibliothèque de blocage qui ouvre le séquenceur MIDI ALSA et attend des événements d'entrée sur elle. Essentiellement, je veux que mon code imprime constamment "in foo loop" et en même temps soit capable de recevoir des événements midi ALSA et les imprimer aussi sur la console (ce que fait start_alsa_listener quand il reçoit un évènement). Le problème est que lorsque j'exécute le code ci-dessus, dès que bar() s'exécute, le contexte ne revient jamais à foo().

start_alsa_listener est une extension rubis C qui ressemble à:

for(;;) { 
    poll(/* args */);  /* wait for input data */ 
    /* print data to console */ 
} 

Peut-être est lié à quelque chose en Ruby je fais mal avec filetage, ou peut-être quelque chose à voir avec sondage, ou peut-être quelque chose à voir avec la façon dont ALSA gère les threads. Toute aide est appréciée.

Répondre

2

Sans le cext, ces deux courent en parallèle. Le GIL ne laissera pas deux threads s'exécuter à la fois avec une extension C, car il ne peut pas savoir qu'il est threadsafe.

+0

ils n'ont pas besoin de fonctionner parallèlement en tant que tels, tant que le contexte est activé et désactivé, de sorte qu'ils ont l'impression de fonctionner en parallèle. Est-ce que ruby ​​fait quelque chose pour empêcher que cela n'arrive? –

+1

Oui. Comme je l'ai dit, l'extension C signifie que le GIL est maintenu par le thread avec l'extension c, ce qui signifie que les autres threads ne peuvent pas fonctionner. –

3

La boucle que vous avez montrée bloquera tout l'interpréteur (en supposant que poll bloque) comme l'a dit Steve. Vous devez appeler poll() en utilisant rb_thread_blocking_region à partir de l'API C Ruby (MRI/YARV).

Questions connexes