英文:
Call Rust DLL function to spawn new thread from C wrapper and return the main thread back to C
问题
C代码如下:
#include "main.h"
#include <stdio.h>
#include "addition.h"
#include <time.h>
#include <unistd.h>
extern void spawn_thread_and_get_back(); // Rust函数:
extern void keep_calling_rust_fn(); // Rust函数:
int main()
{
spawn_thread_and_get_back(); // 这应该在Rust中生成一个带有无限循环的线程
int sleep_seconds = 7;
while(1){
printf("调用Rust函数");
keep_calling_rust_fn(); // 调用Rust函数
}
}
以下是Rust库代码:
async fn counter() {
loop {
println!("Tokio每2秒调用我一次");
// 休眠1秒
sleep(Duration::from_secs(2)).await;
}
}
#[tokio::main]
async fn runForever() {
let counterTask = tokio::spawn(
counter()
);
tokio::try_join!(counterTask);
}
use std::thread;
#[no_mangle]
pub unsafe extern "C" fn spawn_thread_and_get_back() {
let handle = thread::spawn(move || {
// 这里进行一些工作
println!("尝试为Tokio运行时创建新线程");
runForever();
});
handle.join().unwrap();
}
#[no_mangle]
pub unsafe extern "C" fn keep_calling_rust_fn() {
println!("C包装每7秒调用我一次");
someRandomPrintTask();
}
async fn printTask(task_number: u32) {
println!("打印任务 {} -", task_number);
}
async fn someRandomPrintTask() {
let printTask = tokio::spawn(
printTask(10)
);
tokio::try_join!(printTask);
}
我注意到你的代码中有一些错误,我进行了修正。希望这可以帮助你解决问题。
英文:
I have a use case where C wrapper is loading the Rust DLL. Both C and Rust have infinate loop.
C code
#include "main.h"
#include <stdio.h>
#include "addition.h"
#include <time.h>
#include <unistd.h>
extern void spawn_thread_and_get_back(); // Rust function :
extern void keep_calling_rust_fn(); // Rust function :
int main()
{
spawn_thread_and_get_back(); // This should spawn thread with infinite loop in rust
int sleep_seconds = 7;
while(1){
printf("Calling rust function);
keep_calling_rust_fn(); // Call rust function
}
}
and here is the rust lib code
async fn counter() {
loop {
println!("I am getting called by Tokio every 2 seconds");
// Sleep for 1 second
sleep(Duration::from_secs(2)).await;
}
}
#[tokio::main]
async fn runForever() {
let counterTask = tokio::spawn(
counter()
);
tokio::try_join!(counterTask);
}
use std::thread;
#[no_mangle]
pub unsafe extern "C" fn spawn_thread_and_get_back() {
let handle = thread::spawn(move || {
// some work here
println!("Trying to create new thread for Tokio runtime");
runForever();
});
handle.join();
}
#[no_mangle]
pub unsafe extern "C" fn keep_calling_rust_fn() {
println!("I am getting called by C wrapper every 7 second");
someRandomPrintTask();
}
async fn printTask(task_number: u32) {
println!("Print task {} -", task_number);
}
async fn someRandomPrintTask() {
let printTask = tokio::spawn(
printTask(10)
);
tokio::try_join!(printTask);
}
The issue I am facing is once I call the spawn_thread_and_get_back()
from C and never get the thread back to execute while loop
in C
I would like to call the rust DLL from C and spawn seperate thread for rust. And the idea is the caller thread from C will get free once it initializes the rust forever loop thread.
答案1
得分: 0
感谢大家,在上面的评论中讨论后,这是可行的答案。我们只需要更改Rust代码:
async fn counter() {
loop {
println!("每隔2秒,Tokio就会调用我一次");
// 等待1秒
sleep(Duration::from_secs(2)).await;
}
}
#[tokio::main]
async fn runForever() {
let counterTask = tokio::spawn(
counter()
);
tokio::try_join!(counterTask);
}
use std::thread;
#[no_mangle]
pub unsafe extern "C" fn spawn_thread_and_get_back() {
let handle = thread::spawn(move || {
// 在这里进行一些操作
println!("尝试为Tokio运行时创建新线程");
runForever();
});
`handle.join();` *** 更新 - 删除此行,因为它会阻塞主线程,等待handle完成 ***
}
#[no_mangle]
pub unsafe extern "C" fn keep_calling_rust_fn() {
println!("每隔7秒,C包装器就会调用我一次");
someRandomPrintTask();
}
async fn printTask(task_number: u32) {
println!("打印任务 {} -", task_number);
}
#[tokio::main] *** 更新 - 在此处添加了装饰器 ***
async fn someRandomPrintTask() {
let printTask = tokio::spawn(
printTask(10)
);
tokio::try_join!(printTask);
}
英文:
Thanks everyone, After discussing in the comments above, here is the working answer. We just need to change Rust code
async fn counter() {
loop {
println!("I am getting called by Tokio every 2 seconds");
// Sleep for 1 second
sleep(Duration::from_secs(2)).await;
}
}
#[tokio::main]
async fn runForever() {
let counterTask = tokio::spawn(
counter()
);
tokio::try_join!(counterTask);
}
use std::thread;
#[no_mangle]
pub unsafe extern "C" fn spawn_thread_and_get_back() {
let handle = thread::spawn(move || {
// some work here
println!("Trying to create new thread for Tokio runtime");
runForever();
});
`handle.join();` *** Update - Removed this as it was blocking the main thread as it was waiting for handle to finish ***
}
#[no_mangle]
pub unsafe extern "C" fn keep_calling_rust_fn() {
println!("I am getting called by C wrapper every 7 second");
someRandomPrintTask();
}
async fn printTask(task_number: u32) {
println!("Print task {} -", task_number);
}
#[tokio::main] *** Update - Added the decorater here ***
async fn someRandomPrintTask() {
let printTask = tokio::spawn(
printTask(10)
);
tokio::try_join!(printTask);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论