如何使用控制台输出来调试与JNI的pthread交互?

时间:2013-09-18 09:13:44

标签: java c java-native-interface pthreads

我做了一个创建pthread来打印消息的例子。 但输出是出乎意料的。

代码:

System.out.println("Before call native thread");
// invoke the native method to print a message
int socketId = new SocketJNI().createSocket(); //line 7
Thread.sleep(2000);
System.out.println("After call native thread");//line 9: create break point here

C代码:

JNIEXPORT jint JNICALL 
Java_SocketJNI_createSocket(JNIEnv * env, jobject obj)
{
    pthread_t thread;
    pthread_create(&thread, NULL, createSocket, NULL);
    return 0;
}

void* createSocket(void *arg) 
{
    printf("Inside native thread(pthread)");
    pthread_exit(NULL);
}

输出:

Before call native thread
After call native thread
Inside native thread(pthread)

但我认为应该是:

Before call native thread
Inside native thread(pthread)
After call native thread

那么,问题是什么? pthread是如何工作的?

更新

当我到达第8行(在调试时),pthread(在第7行创建)不打印消息,它只打印:

Before call native thread

我等了,等等但不打印 第9行之后:

Before call native thread
After call native thread

2 个答案:

答案 0 :(得分:1)

Thread.sleep(2000)不是你应该同步线程的方式。 如果您希望父级等待子线程,则父线程应该加入子线程。 这是您应该使用的createSocket。

Java_SocketJNI_createSocket(JNIEnv * env, jobject obj)
{
   pthread_t thread;
   pthread_create(&thread, NULL, createSocket, NULL);
   pthread_join(thread,NULL); 
   return 0;
}

答案 1 :(得分:1)

要确保在发送后立即刷新输出,请关闭System.out上的缓冲或使用System.err。在本机端,使用stderr(无缓冲)而不是stdout。您还可以在Java中使用System.out.flush(),在C中使用fflush(stdout)来强制输出任何缓冲数据。

请注意,您仍然可能会得到一些意想不到的结果,因为Java和C不会对输出流使用相同的缓冲区,并且没有什么能阻止两个输出在到达终端的路上混插。但实际上,你可能会在刷新它时立即看到输出(或者如果没有缓冲就输出它)。

至于你的线程实际运行的时间,之后有时会创建它。除非您进行一些显式同步,否则它可能会在您的Java方法返回很久之后才会运行。由系统来启动新线程(Java之外),因此任何因素都可能会延迟线程的启动,包括系统负载,内存交换等。