# Julia function from non-Julia thread and pthread\_join

**URL:** <https://discourse.julialang.org/t/julia-function-from-non-julia-thread-and-pthread-join/97740>\
**Category:** General Usage\
**Tags:** question, ccall, threads\
**Created:** [April 21, 2023, 1:21pm UTC](https://discourse.julialang.org/t/julia-function-from-non-julia-thread-and-pthread-join/97740 "2023-04-21T13:21:19Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![jonas-kr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jonas-kr/32/1810_2.png) [@jonas-kr](https://discourse.julialang.org/u/jonas-kr)\
**Post date:** [April 21, 2023, 1:21pm UTC](https://discourse.julialang.org/t/julia-function-from-non-julia-thread-and-pthread-join/97740/1 "2023-04-21T13:21:19Z")

</div>

Since [46609](https://github.com/JuliaLang/julia/pull/46609) has been merged, it has become possible to have non-Julia threads call Julia functions. Accordingly, I have set up the following MWE of a C++ library `callback_example` compiled with `g++ -shared -o callback_example.so -fPIC -pthread callback_example.cpp`:

```julia
#include <pthread.h>
#include <iostream>

// Define the callback function type
typedef void (*CallbackFunction)();

// Define the thread function that executes the callback
extern "C" void* threadFunc(void* arg)
{
    CallbackFunction callback = reinterpret_cast<CallbackFunction>(arg);
    std::cout << "Thread started.\n";
    callback();
    std::cout << "Thread ended.\n";
    return nullptr;
}

// Define the function that takes the callback and executes it in another thread
extern "C" void executeCallbackInThread(CallbackFunction callback)
{
    // Create a new thread and execute the callback in it
    pthread_t thread;
    pthread_create(&thread, nullptr, &threadFunc, reinterpret_cast<void*>(callback));
}

```

Setting up a Julia interface according to

```julia
lib = joinpath(pwd(), "callback_example")

function callback()
    println("Sample callback executed.")
end

function threaded_callback()
    callback = @cfunction(callback, Cvoid, ())
    ccall((:executeCallbackInThread, lib), Cvoid, (Ptr{Cvoid},), callback)
end

```

yields the desired output

```julia
julia> threaded_callback(); sleep(0.1)
Thread started.
Sample callback executed.
Thread ended.

```

However, if I add another C++ library function that waits for the pthread to finish, i.e.,

```julia
extern "C" void executeCallbackInThreadJoin(CallbackFunction callback)
{
    // Create a new thread and execute the callback in it
    pthread_t thread;
    pthread_create(&thread, nullptr, &threadFunc, reinterpret_cast<void*>(callback));
    // Now wait for the thread to finish -> this breaks julia execution
    pthread_join(thread, nullptr);
}

```

recompile the library and add the corresponding julia interface

```julia
function threaded_callback_join()
    callback = @cfunction(callback, Cvoid, ())
    ccall((:executeCallbackInThreadJoin, lib), Cvoid, (Ptr{Cvoid},), callback)
end

```

the execution gets stuck and won’t terminate without interrupting.

```julia
julia> threaded_callback_join(); sleep(0.1)
Thread started.
Sample callback executed.

```

However, if I replace the callback function by a non-printing one, e.g., `callback() = nothing`, the execution does not get stuck. Is there any way around this behavior? For the sake of convenience, I have attached the source code of the C-library (I have added the jl extension to allow for the upload) and a julia script comprising all the test cases I have mentioned.

Thanks a lot!  
[callback\_example.cpp.jl](https://discourse.julialang.org/uploads/short-url/iQ0FMTOpnnG9f92x7l1bZHI1NGR.jl) (1.1 KB)  
[callback\_example\_interface.jl](https://discourse.julialang.org/uploads/short-url/sLEQBow8J980Xgj93PwZv9OVFfh.jl) (967 Bytes)
