- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Ruby多线程编程初步入门由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
传统程序有一个单独的线程执行,包含该程序的语句或指令顺序执行直到程序终止.
一个多线程的程序有多个线程的执行。在每个线程是按顺序执行的,但是在多核CPU机器上线程可能并行地执行。例如,通常情况下在单一CPU的机器,多个线程实际上不是并行执行的,而是模拟并行交叉的线程的执行.
Ruby的可以使用 Thread 类很容易地编写多线程程序。 Ruby线程是一个轻量级的和高效的在代码中实现并行性。 创建Ruby线程:
要启动一个新线程,关联一个块通过调用Thread.new。将创建一个新的线程执行的代码块,原始线程将立即从Thread.new返回并继续执行下一个语句:
1
2
3
4
5
|
# Thread #1 is running here
Thread
.
new
{
# Thread #2 runs this code
}
# Thread #1 runs this code
|
例如:
这里是一个例子说明,我们如何能够利用多线程的Ruby的程序.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
#!/usr/bin/ruby
def
func1
i=
0
while
i<=
2
puts
"func1 at: #{Time.now}"
sleep(
2
)
i=i+
1
end
end
def
func2
j=
0
while
j<=
2
puts
"func2 at: #{Time.now}"
sleep(
1
)
j=j+
1
end
end
puts
"Started At #{Time.now}"
t1=
Thread
.
new
{func1()}
t2=
Thread
.
new
{func2()}
t1.join
t2.join
puts
"End at #{Time.now}"
|
这将产生以下结果:
1
2
3
4
5
6
7
8
|
Started At Wed May
14
08
:
21
:
54
-
0700
2008
func1 at: Wed May
14
08
:
21
:
54
-
0700
2008
func2 at: Wed May
14
08
:
21
:
54
-
0700
2008
func2 at: Wed May
14
08
:
21
:
55
-
0700
2008
func1 at: Wed May
14
08
:
21
:
56
-
0700
2008
func2 at: Wed May
14
08
:
21
:
56
-
0700
2008
func1 at: Wed May
14
08
:
21
:
58
-
0700
2008
End at Wed May
14
08
:
22
:
00
-
0700
2008
|
线程的生命周期:
创建一个新的线程用 Thread.new。也可以使用了同义词用 Thread.Start 和 Thread.fork.
没有必要启动一个线程在它被创建后,它会自动开始运行时,CPU 资源成为可用.
Thread 类定义了一些方法来查询和处理的线程在运行时。运行一个线程块中的代码调用Thread.new,然后它停止运行.
该块中的最后一个表达式的值是线程的值,可以通过调用 Thread对象值的方法。如果线程运行完成,则该值为线程的返回值。否则,该值方法会阻塞不会返回,直到该线程已完成。 类方法Thread.current返回代表当前线程的 Thread对象。这允许线程操纵自己。类方法 Thread.main返回线程对象代表主线程,thread.this初始线程开始执行Ruby程序开始时.
可以等待一个特定的线程通过调用该线程的Thread.Join方法来完成。调用线程将被阻塞,直到给定线程完成。 线程和异常:
如果在主线程中引发一个异常,并没有任何地方处理,Ruby解释器打印一条消息并退出。在主线程以外的其他线程,未处理的异常导致线程停止运行.
如果线程 t 退出,因为未处理的异常,而另一个线程调用t.join或t.value,那么所发生的异常在 t 中提出的线程 s.
如果 Thread.abort_on_exception 为 false,默认情况下,出现未处理的异常只是杀死当前线程和所有其余的继续运行.
如果想在任何线程中的任何未处理的异常导致解释退出中,设置类方法Thread.abort_on_exception 为 true.
1
2
|
t =
Thread
.
new
{ ... }
t.abort_on_exception =
true
|
线程变量:
一个线程可以正常访问是在范围内的任何变量的线程被创建时。一个线程块的局部变量是线程的局部,而不是共享.
Thread类提供一个特殊的功能,允许通过名称来创建和存取线程局部变量。只需把线程对象,如果它是一个Hash,写入元素使用[] =和读取他们带回使用[].
在这个例子中,每个线程记录计数变量的当前值与该键mycount的一个threadlocal变量.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#!/usr/bin/ruby
count =
0
arr = []
10
.times
do
|i|
arr[i] =
Thread
.
new
{
sleep(rand(
0
)/
10
.
0
)
Thread
.current[
"mycount"
] = count
count +=
1
}
end
arr.
each
{|t| t.join; print t[
"mycount"
],
", "
}
puts
"count = #{count}"
|
这将产生下面的结果:
1
|
8
,
0
,
3
,
7
,
2
,
1
,
6
,
5
,
4
,
9
, count =
10
|
主线程等待子线程完成,然后打印出每个捕获count的值。 线程优先级:
影响线程调度的第一因素,是线程的优先级:高优先级线程之前计划的低优先级的线程。更确切地说,一个线程将只获得CPU时间,如果没有更高优先级的线程等待运行.
可以设置和查询一个Ruby线程对象的优先级=和优先级的优先级。新创建的线程开始在相同的优先级的线程创建它。启动主线程优先级为0.
没有任何方法设置线程优先级在开始运行前。然而,一个线程可以提高或降低自己的优先级的第一次操作。 线程排斥:
如果两个线程共享访问相同的数据,至少有一个线程修改数据,你必须要特别小心,以确保任何线程都不能看到数据处于不一致的状态。这称为线程排除.
Mutex类是一些共享资源的互斥访问,实现了一个简单的信号锁定。即,只有一个线程可持有的锁在给定时间。其他线程可能选择排队等候的锁变得可用,或者可以简单地选择立即得到错误,表示锁定不可用.
通过将所有访问共享数据的互斥体的控制下,我们确保一致性和原子操作。我们的尝试例子,第一个无需mutax,第二个使用mutax: 无需Mutax的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#!/usr/bin/ruby
require
'thread'
count1 = count2 =
0
difference =
0
counter =
Thread
.
new
do
loop
do
count1 +=
1
count2 +=
1
end
end
spy =
Thread
.
new
do
loop
do
difference += (count1 - count2).abs
end
end
sleep
1
puts
"count1 : #{count1}"
puts
"count2 : #{count2}"
puts
"difference : #{difference}"
|
这将产生以下结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
count1 :
1583766
count2 :
1583766
difference :
637992
#!/usr/bin/ruby
require
'thread'
mutex = Mutex.
new
count1 = count2 =
0
difference =
0
counter =
Thread
.
new
do
loop
do
mutex.synchronize
do
count1 +=
1
count2 +=
1
end
end
end
spy =
Thread
.
new
do
loop
do
mutex.synchronize
do
difference += (count1 - count2).abs
end
end
end
sleep
1
mutex.lock
puts
"count1 : #{count1}"
puts
"count2 : #{count2}"
puts
"difference : #{difference}"
|
这将产生以下结果:
1
2
3
|
count1 :
696591
count2 :
696591
difference :
0
|
处理死锁:
当我们开始使用互斥对象的线程排除,我们必须小心地避免死锁。死锁的情况发生时,所有线程正在等待获取另一个线程持有的资源。因为所有的线程被阻塞,他们不能释放其所持有的锁。因为他们可以不释放锁,其它线程不能获得这些锁.
一个条件变量仅仅是一个信号,与资源相关联,并用于特定互斥锁的保护范围内的。当需要一个资源不可用,等待一个条件变量。这一行动释放相应的互斥锁。当一些其他线程发送信号的资源是可用的,原来的线程来等待,并同时恢复上的锁临界区。 例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#!/usr/bin/ruby
require
'thread'
mutex = Mutex.
new
cv = ConditionVariable.
new
a =
Thread
.
new
{
mutex.synchronize {
puts
"A: I have critical section, but will wait for cv"
cv.wait(mutex)
puts
"A: I have critical section again! I rule!"
}
}
puts
"(Later, back at the ranch...)"
b =
Thread
.
new
{
mutex.synchronize {
puts
"B: Now I am critical, but am done with cv"
cv.signal
puts
"B: I am still critical, finishing up"
}
}
a.join
b.join
|
这将产生以下结果:
1
2
3
4
5
|
A
:
I
have critical section, but will wait
for
cv
(Later, back at the ranch...)
B
: Now
I
am critical, but am done with cv
B
:
I
am still critical, finishing up
A
:
I
have critical section again!
I
rule!
|
线程状态:
有五种可能的返回值对应于下表中所示的5个可能的状态。该的状态方法返回的线程状态.
Thread类的方法:
Thread类提供以下方法,它们适用程序的所有线程。这些方法它们使用Thread类的名称来调用,如下所示:
1
|
Thread
.abort_on_exception =
true
|
这里是所有类方法的完整列表:
线程实例方法:
这些方法是适用于一个线程的一个实例。这些方法将被调用,使用一个线程的一个实例如下:
1
2
3
4
5
6
7
|
#!/usr/bin/ruby
thr =
Thread
.
new
do
# Calling a class method new
puts
"In second thread"
raise
"Raise exception"
end
thr.join
# Calling an instance method join
|
这里是所有实例方法的完整列表:
最后此篇关于Ruby多线程编程初步入门的文章就讲到这里了,如果你想了解更多关于Ruby多线程编程初步入门的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在尝试打印 timeval 类型的值。实际上我可以打印它,但我收到以下警告: 该行有多个标记 格式“%ld”需要“long int”类型,但参数 2 的类型为“struct timeval” 程序
我正在编写自己的 unix 终端,但在执行命令时遇到问题: 首先,我获取用户输入并将其存储到缓冲区中,然后我将单词分开并将它们存储到我的 argv[] 数组中。IE命令是“firefox”以启动存储在
我是 CUDA 的新手。我有一个关于一个简单程序的问题,希望有人能注意到我的错误。 __global__ void ADD(float* A, float* B, float* C) { con
我有一个关于 C 语言 CGI 编程的一般性问题。 我使用嵌入式 Web 服务器来处理 Web 界面。为此,我在服务器中存储了一个 HTML 文件。在此 HTML 文件中包含 JavaScript 和
**摘要:**在代码的世界中,是存在很多艺术般的写法,这可能也是部分程序员追求编程这项事业的内在动力。 本文分享自华为云社区《【云驻共创】用4种代码中的艺术试图唤回你对编程的兴趣》,作者: break
我有一个函数,它的任务是在父对象中创建一个变量。我想要的是让函数在调用它的级别创建变量。 createVariable testFunc() [1] "test" > testFunc2() [1]
以下代码用于将多个连续的空格替换为1个空格。虽然我设法做到了,但我对花括号的使用感到困惑。 这个实际上运行良好: #include #include int main() { int ch, la
我正在尝试将文件写入磁盘,然后自动重新编译。不幸的是,某事似乎不起作用,我收到一条我还不明白的错误消息(我是 C 初学者 :-)。如果我手动编译生成的 hello.c,一切正常吗?! #include
如何将指针值传递给结构数组; 例如,在 txt 上我有这个: John Doe;xxxx@hotmail.com;214425532; 我的代码: typedef struct Person{
我尝试编写一些代码来检索 objectID,结果是 2B-06-01-04-01-82-31-01-03-01-01 . 这个值不正确吗? // Send a SysObjectId SNMP req
您好,提前感谢您的帮助, (请注意评论部分以获得更多见解:即,以下示例中的成本列已添加到此问题中;西蒙提供了一个很好的答案,但成本列本身并未出现在他的数据响应中,尽管他提供的功能与成本列一起使用) 我
我想知道是否有人能够提出一些解决非线性优化问题的软件包的方法,而非线性优化问题可以为优化解决方案提供整数变量?问题是使具有相等约束的函数最小化,该函数受某些上下边界约束的约束。 我已经在R中使用了'n
我是 R 编程的初学者,正在尝试向具有 50 列的矩阵添加一个额外的列。这个新列将是该行中前 10 个值的平均值。 randomMatrix <- generateMatrix(1,5000,100,
我在《K&R II C 编程 ANSI C》一书中读到,“>>”和“0; nwords--) sum += *buf++; sum = (sum >>
当下拉列表的选择发生变化时,我想: 1) 通过 div 在整个网站上显示一些 GUI 阻止覆盖 2)然后处理一些代码 3) 然后隐藏叠加层。 问题是,当我在事件监听器函数中编写此逻辑时,将执行 onC
我正在使用 Clojure 和 RESTEasy 设计 JAX-RS REST 服务器. 据我了解,用 Lisp 系列语言编写的应用程序比用“传统”命令式语言编写的应用程序更多地构建为“特定于领域的语
我目前正在研究一种替代出勤监控系统作为一项举措。目前,我设计的用户表单如下所示: Time Stamp Userform 它的工作原理如下: 员工将选择他/她将使用的时间戳类型:开始时间、超时、第一次
我是一名学生,试图自学编程,从在线资源和像您这样的人那里获得帮助。我在网上找到了一个练习来创建一个小程序来执行此操作: 编写一个程序,读取数字 a 和 b(长整型)并列出 a 和 b 之间有多少个数字
我正在尝试编写一个 shell 程序,给定一个参数,打印程序的名称和参数中的每个奇数词(即,不是偶数词)。但是,我没有得到预期的结果。在跟踪我的程序时,我注意到,尽管奇数词(例如,第 5 个词,5 %
只是想知道是否有任何 Java API 可以让您控制台式机/笔记本电脑外壳上的 LED? 或者,如果不可能,是否有可能? 最佳答案 如果你说的是前面的 LED 指示电源状态和 HDD 繁忙状态,恐怕没
我是一名优秀的程序员,十分优秀!