如何在多线程中使用RpcClient
How to use RpcClient in multiple threads
我正在编写一个程序,它可以在终端中打印出您的 SOL 余额,但在获取它时会显示一个加载指示器。我正在使用 solana_client 箱子中的 RpcClient 来获取我的 SOL 余额,但是在一个新线程上,所以我可以在请求为 运行.
时在主线程上旋转加载指示器
我的问题是,如果我尝试在传递给 thread::spawn()
:
的函数中使用 RpcClient 的指针,我会收到错误消息
fn main() {
let url = "https://api.testnet.solana.com".to_string();
let client = RpcClient::new(url);
let pubkey = Pubkey::from_str(ADDRESS).unwrap();
get_balance(&client, &pubkey);
}
fn get_balance(client: &RpcClient, pubkey: &Pubkey) {
let (tx, rx): (Sender<u64>, Receiver<u64>) = mpsc::channel();
let pubkey = pubkey.clone();
thread::spawn(move || {
let balance = client.get_balance(&pubkey).unwrap();
tx.send(balance)
.expect("failed to send back result throught tx channel");
});
let balance = spin(rx);
println!("balance: {}", balance);
}
错误:
error[E0759]: `client` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
--> src/main.rs:24:19
|
21 | fn get_balance(client: &RpcClient, pubkey: &Pubkey) {
| ---------- this data with an anonymous lifetime `'_`...
...
24 | thread::spawn(move || {
| ___________________^
25 | | let balance = client.get_balance(&pubkey).unwrap();
26 | | tx.send(balance)
27 | | .expect("failed to send back result throught tx channel");
28 | | });
| |_____^ ...is used here...
|
我试图将 client
变量设为静态,但这导致了另一个错误:
...
let client: &'static RpcClient = &RpcClient::new(url);
...
fn get_balance(client: &'static RpcClient, pubkey: &Pubkey) {
...
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:15:39
|
15 | let client: &'static RpcClient = &RpcClient::new(url);
| ------------------ ^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
19 | }
| - temporary value is freed at the end of this statement
如果我尝试在 get_balance
函数中克隆 client
,我会得到同样的错误,就像我在 pubkey
.
中所做的那样
我可以通过传递 url 并在线程内创建一个新的 RpcClient
来解决这个问题,但我试图理解为什么我当前的实现不起作用,以及我如何使用线程时应该处理此类问题。
感谢 我能够通过将客户端包装在 Arc
:
中来解决问题
fn main() {
let url = "https://api.testnet.solana.com".to_string();
let client = Arc::new(RpcClient::new(url));
let pubkey = Pubkey::from_str(ADDRESS).unwrap();
get_balance(&client, &pubkey);
}
fn get_balance(client: &Arc<RpcClient>, pubkey: &Pubkey) {
let (tx, rx): (Sender<u64>, Receiver<u64>) = mpsc::channel();
let client = client.clone();
let pubkey = pubkey.clone();
thread::spawn(move || {
let balance = client.get_balance(&pubkey).unwrap();
tx.send(balance)
.expect("failed to send back result throught tx channel");
});
let balance = spin(rx);
println!("balance: {}", balance);
}
我还发现 帮助我理解了为什么我的原始代码不起作用。
我正在编写一个程序,它可以在终端中打印出您的 SOL 余额,但在获取它时会显示一个加载指示器。我正在使用 solana_client 箱子中的 RpcClient 来获取我的 SOL 余额,但是在一个新线程上,所以我可以在请求为 运行.
时在主线程上旋转加载指示器我的问题是,如果我尝试在传递给 thread::spawn()
:
fn main() {
let url = "https://api.testnet.solana.com".to_string();
let client = RpcClient::new(url);
let pubkey = Pubkey::from_str(ADDRESS).unwrap();
get_balance(&client, &pubkey);
}
fn get_balance(client: &RpcClient, pubkey: &Pubkey) {
let (tx, rx): (Sender<u64>, Receiver<u64>) = mpsc::channel();
let pubkey = pubkey.clone();
thread::spawn(move || {
let balance = client.get_balance(&pubkey).unwrap();
tx.send(balance)
.expect("failed to send back result throught tx channel");
});
let balance = spin(rx);
println!("balance: {}", balance);
}
错误:
error[E0759]: `client` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
--> src/main.rs:24:19
|
21 | fn get_balance(client: &RpcClient, pubkey: &Pubkey) {
| ---------- this data with an anonymous lifetime `'_`...
...
24 | thread::spawn(move || {
| ___________________^
25 | | let balance = client.get_balance(&pubkey).unwrap();
26 | | tx.send(balance)
27 | | .expect("failed to send back result throught tx channel");
28 | | });
| |_____^ ...is used here...
|
我试图将 client
变量设为静态,但这导致了另一个错误:
...
let client: &'static RpcClient = &RpcClient::new(url);
...
fn get_balance(client: &'static RpcClient, pubkey: &Pubkey) {
...
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:15:39
|
15 | let client: &'static RpcClient = &RpcClient::new(url);
| ------------------ ^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
19 | }
| - temporary value is freed at the end of this statement
如果我尝试在 get_balance
函数中克隆 client
,我会得到同样的错误,就像我在 pubkey
.
我可以通过传递 url 并在线程内创建一个新的 RpcClient
来解决这个问题,但我试图理解为什么我当前的实现不起作用,以及我如何使用线程时应该处理此类问题。
感谢 Arc
:
fn main() {
let url = "https://api.testnet.solana.com".to_string();
let client = Arc::new(RpcClient::new(url));
let pubkey = Pubkey::from_str(ADDRESS).unwrap();
get_balance(&client, &pubkey);
}
fn get_balance(client: &Arc<RpcClient>, pubkey: &Pubkey) {
let (tx, rx): (Sender<u64>, Receiver<u64>) = mpsc::channel();
let client = client.clone();
let pubkey = pubkey.clone();
thread::spawn(move || {
let balance = client.get_balance(&pubkey).unwrap();
tx.send(balance)
.expect("failed to send back result throught tx channel");
});
let balance = spin(rx);
println!("balance: {}", balance);
}
我还发现