引用和复制/恢复之间的结果有何不同?
背景:我目前正在研究分布式系统。关于远程过程调用的参考参数的传递,该书指出:“通过引用的调用已被复制/恢复替换。虽然这并不总是相同,但它已经足够了”。我理解原则上如何通过引用和复制/恢复工作,但我没有看到结果的差异在哪里?
答案 0 :(得分:17)
取自here的例子。
主要代码:
#include <stdio.h>
int a;
int main() {
a = 3;
f( 4, &a );
printf("%d\n", a);
return 0;
}
按值调用:
f(int x, int &y){
// x will be 3 as passed argument
x += a;
// now a is added to x so x will be 6
// but now nothing is done with x anymore
a += 2*y;
// a is still 3 so the result is 11
}
传入值并且对传入的变量的值没有影响。
按参考号召集:
f(int x, int &y){
// x will be 3 as passed argument
x += a;
// now a is added to x so x will be 6
// but because & is used x is the same as a
// meaning if you change x it will change a
a += 2*y;
// a is now 6 so the result is 14
}
传入参考。有效地,函数中的变量与外部变量相同。
使用复制/还原进行呼叫:
int a;
void unsafe(int x) {
x= 2; //a is still 1
a= 0; //a is now 0
}//function ends so the value of x is now stored in a -> value of a is now 2
int main() {
a= 1;
unsafe(a); //when this ends the value of a will be 2
printf("%d\n", a); //prints 2
}
传入值并且对函数结尾处传递的变量值没有影响,此时函数变量的FINAL值存储在传入的变量中。
通过引用调用和复制/恢复之间的基本区别是,对函数变量的更改将不会显示在传入的变量中,直到函数结束后才会立即看到引用调用的变化。 / p>
答案 1 :(得分:8)
通过复制/恢复进行呼叫是一种特殊情况的呼叫引用,其中提供的引用对于呼叫者是唯一的。在函数结束之前,不会保存引用值的最终结果。
当通过引用调用RPC中的方法时,这种类型的调用很有用。实际数据将发送到服务器端,最终结果将发送到客户端。这将减少流量,因为服务器不会每次都更新引用。
答案 2 :(得分:0)
引用调用:
在按引用调用中,我们传递一个指向被调用函数的指针。该指针指向的数据发生的任何更改都将立即反映出来。
假设如果要对该数据进行大量更改,虽然不会在本地产生太多成本,但在网络成本方面会很昂贵,因为每次更改数据都必须复制回客户端。
C 代码:
void addTwo(int *arr, int n){
for(int i=0;i<n;i++){
arr[i]+=2; //change is happening in the original data as well
}
}
int main(){
int arr[100]={1,2,3,...}; // assuming it to be initialised
addTwo(arr,100);
}
通过复制/恢复调用:
在 call-by-copy/restore 中,思想是当函数被调用时引用数据,只有对数据所做更改的最终结果被复制回原始数据(当函数即将return) 在函数调用过程中不对原始数据做任何改动,只需要一次传输回客户端。
在下面的 C
代码中,arr
指向的数据被复制到函数中,并在对本地数据的所有更改完成后存储回 arr
。
C 代码:
void addTwo(int *arr, int n){
// copy data locally
larr = (int*)malloc(n*sizeof(int));
for(int i=0;i<n;i++){
larr[i]=arr[i];
}
for(int i=0;i<n;i++){
// change is happening to the local variable larr
larr[i]+=2;
}
//copy all the changes made to the local variable back to the original data
for(int i=0;i<n;i++){
arr[i]=larr[i];
}
}
int main(){
int arr[100]={1,2,3,...}; // assuming it to be initialised
addTwo(arr,100);
}
注意:上面显示的代码不代表实际的 RPC 实现,只是概念的说明。在真正的 RPC 中,消息中传递的是完整的数据,而不是指针(地址)。