Search code examples
javacjava-native-interfacepthreads

How can I use console output to debug pthread interaction with JNI?


I made an example which creates a pthread to print a message. But the output is unexpected.

Code:

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 code:

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);
}

Output:

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

But I think it should be:

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

So, what is the problem? How does pthread work?

Update:

When I reach line 8(on debugging), the pthread(create in line 7) don't print message, It print only:

Before call native thread

I wait, and wait but not thing print After line 9:

Before call native thread
After call native thread

Solution

  • To ensure your output is flushed as soon as you send it, either turn off buffering on System.out or use System.err. On the native side, use stderr (unbuffered) instead of stdout. You can also use System.out.flush() in Java and fflush(stdout) in C to force output of any buffered data.

    Note that you still might get some unexpected results, since Java and C don't use the same buffers for output streams, and there's nothing preventing the two outputs from intermixing on their way to the terminal. In practice, though, you'll likely see the output as soon as you flush it (or as soon as it's output if unbuffered).

    As for when your thread actually runs, it'll be sometime after you create it. Unless you put in some explicit synchronization, it may not run until long after your Java method has returned. It's up to the system to start the new thread (outside of Java), so any number of factors might delay the thread's start, including system load, memory swapping, etc.