Ruby';线程的速度
我有以下代码可以线程安全地写入文件:Ruby';线程的速度,ruby,multithreading,file-io,thread-safety,Ruby,Multithreading,File Io,Thread Safety,我有以下代码可以线程安全地写入文件: threads = [] @@lock_flag = 0 @@write_flag = 0 def add_to_file old_i = 0 File.open( "numbers.txt", "r" ) { |f| old_i = f.read.to_i } File.open( "numbers.txt", "w+") { |f| f.write(old_i+1) } #puts old_i end File.ope
threads = []
@@lock_flag = 0
@@write_flag = 0
def add_to_file
old_i = 0
File.open( "numbers.txt", "r" ) { |f| old_i = f.read.to_i }
File.open( "numbers.txt", "w+") { |f| f.write(old_i+1) }
#puts old_i
end
File.open( "numbers.txt", "w") { |f| f.write(0) } unless File.exist? ("numbers.txt")
2000.times do
threads << Thread.new {
done_flag = 0
while done_flag == 0 do
print "." #### THIS LINE
if @@lock_flag == 0
@@lock_flag = 1
if @@write_flag == 0
@@write_flag = 1
add_to_file
@@write_flag = 0
done_flag = 1
end
@@lock_flag = 0
end
end
}
end
threads.each {|t| t.join}
threads=[]
@@锁定标志=0
@@写入标志=0
def将_添加到_文件
old_i=0
open(“numbers.txt”,“r”){| f | old_i=f.read.to_i}
open(“numbers.txt”、“w+”{| f | f.write(old|i+1)}
#把老èi
结束
打开(“numbers.txt”,“w”){| f | f.write(0)}除非File.exist?(“numbers.txt”)
2000.00倍
线程我不知道你怎么能称之为线程安全,而它根本不是。由于比赛条件的原因,您不能使用简单的变量来确保安全。在测试标志是否为零和将其设置为一之间会发生什么?你根本不知道。如果你够倒霉的话,任何事情都可能而且最终都会在那短暂的时间内发生
可能发生的情况是,print
语句会导致线程暂停足够长的时间,从而使损坏的锁定机制停止工作。当使用Ruby 1.9.2测试该示例时,它甚至没有完成,打印点似乎永远不会消失
您可能希望尝试使用互斥体重新写入它:
write_mutex = Mutex.new
read_mutex = Mutex.new
2000.times do
threads << Thread.new {
done_flag = false
while (!done_flag) do
print "." #### THIS LINE
write_mutex.synchronize do
read_mutex.synchronize do
add_to_file
done_flag = true
end
end
end
}
end
write_mutex=mutex.new
read_mutex=mutex.new
2000.00倍
线程我不知道你怎么能称之为线程安全,而它根本不是。由于比赛条件的原因,您不能使用简单的变量来确保安全。在测试标志是否为零和将其设置为一之间会发生什么?你根本不知道。如果你够倒霉的话,任何事情都可能而且最终都会在那短暂的时间内发生
可能发生的情况是,print
语句会导致线程暂停足够长的时间,从而使损坏的锁定机制停止工作。当使用Ruby 1.9.2测试该示例时,它甚至没有完成,打印点似乎永远不会消失
您可能希望尝试使用互斥体重新写入它:
write_mutex = Mutex.new
read_mutex = Mutex.new
2000.times do
threads << Thread.new {
done_flag = false
while (!done_flag) do
print "." #### THIS LINE
write_mutex.synchronize do
read_mutex.synchronize do
add_to_file
done_flag = true
end
end
end
}
end
write_mutex=mutex.new
read_mutex=mutex.new
2000.00倍
线程首先,有一些宝石可以使这类事情变得更容易<代码>threach
和jruby_threach
(“线程化的每个”)都是我写的,虽然我对实现非常不满意,并会在某个时候设法使它们更干净,但当您有安全的代码时,它们工作得很好
(1..100).threach(2) {|i| do_something_with(i)} # run method in two threads
或
您还应该查看peach
和parallel
以了解其他易于与多线程并行工作的示例
除了已经指出的问题之外——您的循环不是线程安全的——所有这些都无关紧要,因为您正在调用的代码(add_to_file)不是线程安全的。你在线程间随意打开和关闭同一个文件,这会给你带来问题。我似乎不明白您想做什么,但您需要记住,您完全不知道不同线程中的事情将以什么顺序运行。首先,有一些宝石可以让这类事情变得更简单<代码>threach
和jruby_threach
(“线程化的每个”)都是我写的,虽然我对实现非常不满意,并会在某个时候设法使它们更干净,但当您有安全的代码时,它们工作得很好
(1..100).threach(2) {|i| do_something_with(i)} # run method in two threads
或
您还应该查看peach
和parallel
以了解其他易于与多线程并行工作的示例
除了已经指出的问题之外——您的循环不是线程安全的——所有这些都无关紧要,因为您正在调用的代码(add_to_file)不是线程安全的。你在线程间随意打开和关闭同一个文件,这会给你带来问题。我似乎不明白您想做什么,但您需要记住,您完全不知道不同线程中的事情将以什么顺序运行。这是ruby 1.8还是1.9?这是ruby 1.8还是1.9?print
并没有加快处理速度,它只是让无效的锁定系统以某种方式“工作”。互斥版本对我来说运行得很好,原始版本永远不会完成。如果您使用的是线程,并且希望同步,那么确实应该使用互斥锁。它们非常简单,如果你使用尝试锁定
并仔细规划,就永远不会死锁。打印
不会加快处理速度,只会让无效的锁定系统以某种方式“工作”。互斥版本对我来说运行得很好,原始版本永远不会完成。如果您使用的是线程,并且希望同步,那么确实应该使用互斥锁。它们非常简单,如果您使用try\u lock
并仔细规划,就永远不会死锁。