8.1.1fork执行多线程计算

多线程计算是指在执行计算任务时,多个子任务使用各自独立的线程,同时计算的处理方式。在集算器中,可以使用fork语句来执行多线程计算。我们先用下面的例子了解fork语句的使用:

 

A

B

1

$(demo) select * from EMPLOYEE

[Sales,R&D,Finance,Production]

2

fork B1

=A1.select(DEPT==A2)

3

 

=B2.minp(BIRTHDAY)

4

 

return B3

A1中,从数据库中读出EMPLOYEE表中的数据:

A2中用fork语句执行多线程计算,分别选出B1的各个部门中年龄最大的员工。执行后,A2中的结果如下:

在用多线程执行代码时,用fork循环序列参数,会根据参数序列的长度,分为多个线程同时执行fork语句的代码块,代码块中用return返回的结果将在主线程中拼为序列。

使用fork虽然也类似于循环计算,但是它与一般的for循环是不同的。在for循环中,代码块是按顺序用单线程完成循环计算的,而fork根据序列参数执行的计算是同时处理的。

为了进一步了解各个线程的执行情况,我们在A2的代码块中用output函数输出信息到控制台:

 

A

B

C

1

$(demo) select * from EMPLOYEE

[Sales,R&D,Finance,Production]

 

2

fork B1

>output(A2+"-begin")

=A1.select(DEPT==A2)

3

 

=B2.minp(BIRTHDAY)

>output(A2+"-end")

4

 

return B3

 

A2的代码块执行时,当计算开始和结束时,在B2C3中分别输出信息。执行后,在控制台中可以看到输出结果如下:

从输出结果中可以看出,多个子任务有可能会同时计算,有的子任务也有可能需要等待资源才能开始执行。在多线程任务执行时,是由系统分配的,系统将会根据CPU的空闲情况来控制各个子任务的执行。每个子任务的计算时间会受本身的计算量以及执行线程的影响,多线程任务的执行在不同情况下也经常是有区别的。

 

在执行多线程计算时,也可以使用多个参数,如:

 

A

B

C

1

$(demo) select * from EMPLOYEE

[Sales,R&D,Finance,Production]

[Texas,Illinois,Ohio,Florida]

2

fork B1,["F","F","F","F"],C1

=A1.select(DEPT==A2(1) && GENDER==A2(2) && STATE==A2(3))

 

3

 

=B2.minp(BIRTHDAY)

 

4

 

return B3

 

A2执行多线程计算时,使用了3个参数,计算时将会按顺序匹配,即使用的参数依次为[Sales,F,Texas], [R&D,F,Illinois], [Finance,F,Ohio] [Production,F,Florida]。此时寻找最大年龄的员工时,指定了部门、性别和所在州。A2中的计算结果如下:

如果执行多线程计算时使用多个参数,那么各个参数的序列长度应该是相等的。

我们可以注意到,在上面的代码中,查找各个部门的员工时,性别要求是同样的,此时可以将参数写为单值。如下面的例子:

 

A

B

C

1

$(demo) select * from EMPLOYEE

[Sales,R&D,Finance,Production]

[Texas,Illinois,Ohio,Florida]

2

fork B1,"F",C1

=A1.select(DEPT==A2(1) && GENDER==A2(2) && STATE==A2(3))

>A1=B2

3

 

return B2

 

调用多线程计算时,单值参数会被复制到每个线程中,使用相同的参数值。另外,在这里代码块用return返回的并不是单条记录,而是排列,此时A2中的结果也会是排列构成的序列:

另外,在代码块中的C2中,将A1中的数据修改为选出的子程序中选出的排列。但是运行后,查看A1可以发现,A1中的数据并未被多线程运算的代码块修改。实际上,多线程运算的子程序在执行时,会各自复制当前的网格状态,是互相独立、互不影响的。因此它们也不能影响主代码中的数据。

fork语句除了可以用于多线程运算,也可以用于集群计算,相关内容请看后面10章集群计算 中的讲述。