2011-02-18 5 views
10

스레드의 묶음을 분기하고 각각의 진행 출력을 STDERR로 인쇄하려고합니다. 출력이 라인 - 원 자성을 유지하도록하는 방법, 즉 동일한 출력 라인에서 다른 스레드의 출력을 뒤죽박죽으로 처리하지 못하게하려면 어떻게해야합니까?출력을 엉망으로 만들지 않고 Ruby에서 병렬 작업의 출력을 인쇄하는 가장 쉬운 방법은 무엇입니까?

# run this a few times and you'll see the problem 
threads = []  
10.times do 
    threads << Thread.new do   
    puts "hello" * 40 
    end  
end 
threads.each {|t| t.join} 

답변

26

puts는 행과 별도로 새 행을 쓸 수 있기 때문에 경쟁 조건이 있습니다. 당신은 멀티 스레드 응용 프로그램에서 풋을 사용하여 소음의 종류를 볼 수 있습니다 :

thread 0thread 1 
thread 0thread 2 
thread 1 
thread 0thread 3 
thread 2 
thread 1 

대신, 인쇄 또는

print "thread #{i}" + "\n" 
print "thread #{i}\n" 
printf "thread %d\n", i 

또는, STDERR에 기록 할 이후의 printf :

$stderr.print "thread #{i}\n" 

Ruby의 버그입니까? 코멘트가 표준으로 취해지면 안된다. 다음은 MRI 1.8.7에서 IO.puts의 정의입니다. 2.2.2 :

/* 
* call-seq: 
*  ios.puts(obj, ...) => nil 
* 
* Writes the given objects to <em>ios</em> as with 
* <code>IO#print</code>. Writes a record separator (typically a 
* newline) after any that do not already end with a newline sequence. 
* If called with an array argument, writes each element on a new line. 
* If called without arguments, outputs a single record separator. 
* 
*  $stdout.puts("this", "is", "a", "test") 
* 
* <em>produces:</em> 
* 
*  this 
*  is 
*  a 
*  test 
*/ 
+0

와우, 나는 방금 내 로그 파일 중 일부와 함께 살고 있습니다. 쉬운 수정처럼 보입니다. –

+1

웨인이'print '라는 텍스트를 사용하는 것에 대한 확장과 마찬가지로, 일부 텍스트'+ "\ n"','print "일부 텍스트 \ n"'도 괜찮습니다. 'print 'some text', "\ n"'하지 마라. 그 쉼표는 경주 누출이있는 곳인 것처럼 보입니다. 내가 기억한다면 Perl과 같은 문제를 보곤했다. –

관련 문제