从c中调用python函数,传递一些浮点数组并在其上存储数据

2024-10-02 00:20:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我在一个天文应用程序里工作。我需要读取一个casams文件,它很容易从python读取。你知道吗

问题是,我正在与CUDA合作,我需要将文件数据保存为u,v坐标,真实和想象的可见性和权重,在主机数组中。你知道吗

是否可以从C调用python函数,传递数组和文件名,并在python函数中填充它们?你知道吗

怎么办?你知道吗

有没有一种特殊的方法来编译这个文件?你知道吗

提前谢谢。你知道吗


Tags: 文件数据方法函数应用程序文件名数组cuda
1条回答
网友
1楼 · 发布于 2024-10-02 00:20:08

每当任何线程(主线程除外)开始执行“factorial(int number)”方法时,该线程都会将“number”的一个副本作为局部变量保存到自己的堆栈中,因此任何其他线程都不可能更改“number”的值

然而,如果“number”值来自任何共享对象(由多个线程共享),并且如果它被多个线程复制到stack&;在某些线程更改了该值之后,在这种情况下可能会出现数据不一致的情况(请检查“volatile”)

网友
2楼 · 发布于 2024-10-02 00:20:08

多个线程确实可以安全地调用MathUtils.factorial()

每次激活factorial都会有自己的f副本,可以单独访问。这就是“局部变量”的含义

参数number不被修改,在任何情况下都像一个局部变量'factorial'

至于你在评论中的问题。不,代码只有一份,不需要再多拿一份。但是每个线程都有自己的代码执行,所以如果将其视为一个“单独的副本”会有所帮助,那么在概念上不会造成太大的伤害

网友
3楼 · 发布于 2024-10-02 00:20:08

您需要了解的具体机制是堆栈

每个线程都有自己的堆栈。堆栈是一种传统的后进先出设置:可以“推”堆栈上的内容,也可以“弹出”堆栈上的内容,这将检索并删除最近推的内容

每个线程都有自己独特的堆栈。堆栈用于局部变量执行指针。想象一下这个代码:

public static void main(String[] args) {
    a(5);
    System.out.println("Done");
}

public static void a(int x) {
    b();
    System.out.println("In a: " + a);
}

public static void b() {}

现在想象你是一个CPU。你只是被指向一条指令,应该运行它。你不懂java,也不知道循环是什么。你只知道基本的指令,包括“去”。但你只有这些

b()运行完毕后,您如何知道返回到哪里?您怎么知道必须跳回方法的中点并继续System.out.println("In a")

堆栈就是答案。当执行b()时,引擎盖下发生的是:

PUSH [position in this method we're at right now]
GOTO [position of the start of the b method]

b()方法以一条指令结束,这意味着:从堆栈中弹出一个数字,然后转到该数字

局部变量存储在堆栈上。所有这些的指令集基本上是:

1 PUSH 4 // position to return back to once a is done
2 PUSH 5 // from a(5)
3 GOTO 8 // a method
4 PUSH 7
5 CREATE_OBJECT "Done" // pushes pos of new object on stack
6 GOTO [position of System.out.println]
7 EXIT_APPLICATION

8 PUSH 10 // position to return back to
9 GOTO 16 // b() method
10 CREATE_OBJECT "In a: " // pushes pos of new object on stack
11 FLIP // flip the top two stack entries
12 CONCAT_STRINGS
13 PUSH 15 // position to return back to
14 GOTO [position of System.out.println]
15 RET // pop number and go to it

16 RET

(这是非常简单的;CPU和字节码比这复杂得多,但希望它能让人明白这一点!)

堆栈作为一个概念解释了java的工作原理:

  • 方法是“可重入的”,每次方法运行时,每个局部变量和参数都是唯一的副本。这是因为它们是由堆栈上的东西表示的,当然,你可以继续向堆栈中添加东西。从这个意义上说,堆栈是一个相对的东西:“System.out.println(b)”,如果b是一个局部变量或参数,就像是一条指令,读取一本书中的一行“在你当前阅读的地方的上面两行”(只要你继续阅读,这将是一个新行),而不是一条指令,读取“本书中的第8行”,每次都是同一行
  • Java是按值传递的,这意味着你得到的一切都是副本:
int x = 5;
add1(x);
System.out.println(x);

public void add1(int x) {
   x = x + 1;
}

上面打印的是5而不是6,因为add1(x)是以下内容的缩写:

PUSH current_value_of_whatever_the_x_variable_holds
CALL add1

add1将对这个推送值进行操作,而不是对x变量进行操作。当我们涉及到物体时,它会变得有点复杂(因为java中的对象是由它们的引用来表示的:指针。想象一个对象是一所房子,而引用更像是一个地址。我可以有一个我房子的地址,然后在一张纸上递给你一份该地址的副本。你可以拿一支笔随意更改那张纸,这不会影响我的地址簿或地址。)我的房子。但是如果你开车到房子里,把一块砖头扔进窗户,即使我递给你一份我的通讯录,那仍然是我的窗户。所以:

List<String> list = new ArrayList<String>();
list.add("Hello");
add1(list);
System.out.println(list);

public void add1(List<String> list) {
  list.add("World!");
}

这个打印^{。因为.在java中相当于“开车去地址list所指的房子”。如果我写了list = List.of("Hello", "World!"),似乎什么也不会发生,因为=相当于java:擦除地址卡并在其上写一个新地址。这不会影响我的房子和通讯录

相关问题 更多 >

    热门问题