Load Lua script once, execute in multiple states in multiple threads - c++

I would like to load a Lua script into my C++ program, and then invoke that script multiple times in separate threads. I'm trying to avoid loading the script in each thread (why go through that overhead).
I'm thinking something like this in the C++ program:
create lua state L
load script into L
and in n threads do:
create local lua state Si (i = 1..n, i.e., separate state per thread)
grab "compiled" script from L and invoke in the context in Si
Is there a "standard" approach to doing this? The primary goal is to avoid having each thread load the script. The script may also be executed multiple times in state Si. Note that the scripts running in separate threads are not cooperating (i.e., they know nothing about each other and we would like to keep it that way).

As I said in a comment, I dont think you can do what you want with c++ threads without data races or mutexes that block all parallel execution.
A single lua state does not seem to be designed to be used by multiple threads and lua threads dont support multithreading either and there is no way to move data from a completely separate state to another magically.
However what you can try is to "compile" the lua scripts on a state by doing loadstring and then dump and save that in a safe way so that you can access it from all threads to load the script faster from the bytecode directly with loadstring.
Otherwise you would need to keep all states separate and do all communication between them by C++ and ensure thread safety there.

Related

Invoking Tcl proc in multithreaded mode

My function func() is being called by multiple threads. (Each thread will call this function only once.)
From inside the func(), I want each thread to call a Tcl proc named tcl_proc_name (which takes no arguments).
For this, I did like this
Tcl_Eval( Tcl_CreateInterp() , "tcl_proc_name");
But it somehow this code is not able to invoke the Tcl proc.
Am I missing something?
Every Tcl interpreter (i.e., every instance of Tcl_Interp) is strongly bound by design to the thread that creates it; the implementation internally uses thread-specific data extensively so as to virtually completely avoid the need for major locks (like the Global Interpreter Lock that bedevils performant multithreaded Python code). Tcl commands are utterly bound to the interpreter that contains them. You have to either:
Send messages to a single thread to perform the action. (See the Tcl_QueueEvent() function, or use the Thread package's thread::send command from the Tcl level.)
Duplicate the command in multiple interpreters, one per thread. That might be easy or complex in your application.
For avoidance of all doubt: you cannot safely use a Tcl interpreter from multiple threads. It will not work; guaranteed. It will cause crashes.

What is the best IPC method for first process to remain running while subsequent processes pass params only?

I need to develop a process that starts and continues running when no other such process is running on the local host. Subsequent local instances of this process (spawned by other processes, i.e. not forked child/parent) then need to execute only to somehow pass their command line parameters to the original process for processing and then exit as soon as possible.
I know I need IPC to achieve this while I need to keep the overhead of both footprint and execution speed to a bare minimum, so this rules out sockets and other network based IPC such as message queues.
The spawned processes need to somehow be aware of the master process. There is no requirement for IPC across hosts.
I'm thinking about using a named pipe but want to know the alternatives. For example, would an anonymous pipe via a shared handle written to file be more efficient?
In this case the mechanism is important; not the language and environment contained in examples. I will implement the mechanism in C or C++.
The MAN page for msgrcv() and msgsnd() give everything you need to know to perform the desired operations.
Suggest reading: how to use msgrcv for an example of how to use those functions.

Game Engine Multithreading with Lua

I'm designing the threading architecture for my game engine, and I have reached a point where I am stumped.
The engine is partially inspired by Grimrock's engine, where they put as much as they could into LuaJIT, with some things, including low level systems, written in C++.
This seemed like a good plan, given that LuaJIT is easy to use, and I can continue to add API functions in C++ and expand it further. Faster iteration is nice, the ability to have a custom IDE attached to the game and edit the code while it runs is an interesting option, and serializing from Lua is also easy.
But I am stumped on how to go about adding threading. I know Lua has coroutines, but that is not true threading; it's basically to keep Lua from stalling as it waits for code that takes too long.
I originally had in mind to have the main thread running in Lua and calling C++ functions which are dispatched to the scheduler, but I can't find enough information on how Lua functions. I do know that when Lua calls a C++ function it runs outside of the state, so theoretically it may be possible.
I also don't know whether, if Lua makes such a call that is not supposed to return anything, it will hang on the function until it's done.
And I'm not sure whether the task scheduler runs in the main thread, or if it is simply all worker threads pulling data from a queue.
Basically meaning that, instead of everything running at once, it waits for the game state update before doing anything.
Does anyone have any ideas, or suggestions for threading?
In general, a single lua_State * is not thread safe. It's written in pure C and meant to go very fast. It's not safe to allow exceptions go through it either. There's no locks in there and no way for it to protect itself.
If you want to run multiple lua scripts simultaneously in separate threads, the most straightforward way is to use luaL_newstate() separately in each thread, initialize each of them, and load and run scripts in each of them. They can talk to the C++ safely as long as your callbacks use locks when necessary. At least, that's how I would try to do it.
There are various things you could do to speed it up, for instance, if you are loading copies of a single script in each of the threads, you could compile it to lua bytecode before you launch any of the threads, then put the buffer into shared memory, and have the scripts load the shared byte code without changing. That's most likely an unnecessary optimization though, depending on your application.

V8 order of instantiating the variables (multi-thread)

I'm new with Google's V8 and I'm not sure how to fully use the variable types they give. I'll start by explaining what i wish to flow to be:
In the main thread I want to compile the JS scripts.
In several threads I want to run scripts when I "add" to the context different information using instance->SetAccessor(...) or prototype->Set(...) (or any other option if there is.
I am not sure when I need to do the following:
where and when to create the v8::handleScope? is creating one in the main thread is enough? or I need one for each thread?
where and when to create v8::isolate and v8::locker? should it be per thread or not? should it be before or after the v8::handleScope?
Any info will help (:
If you want to run the scripts in parallel from each thread with no cross-thread sharing, then each thread needs its own isolate. You may or may not actually need one for the main thread, or you could maybe use the default isolate. I'd recommend making sure that the default isolate has been initialized before running any threads though, just in case one of your other threads ends up initializing it. You should be ok if you are using isolates but it won't do any harm to be sure.
If you need cross-thread sharing of objects etc then you'll need to research this and it is likely to be difficult. Not even sure if v8 can really support it yet or not. Having separate isolates and avoiding sharing of objects is much easier.
You should be able to compile your scripts in the context of an isolate intended for the thread that is going to execute it in the main thread and then pass the script and the isolate to the thread and not touch either again in the main thread until the worker thread is done with it. This ought to work, but I've not checked if v8 checks the thread-id that the isolate was created in and the one it executes in. It's worth writing a little test app to check that this will work.
The other option is to check the compilation in the main thread and compile it again in the worker thread and encapsulate the isolate in the thread. This is the way I have done it in the past. It's easier but less efficient.
The handle scope should be allocated on the stack only in the functions where it is needed. Don't use a global variable for the handle scope or allocate it on the heap.
Your compiled script should use a persistent handle.
Enter the handle scope after you have entered the isolate scope.

Hibernating/restarting a thread

I'm looking for a way to restart a thread, either from inside that thread's context or from outside the thread, possibly from within another process. (Any of these options will work.) I am aware of the difficulty of hibernating entire processes, and I'm pretty sure that those same difficulties attend to threads. However, I'm asking anyway in the hopes that someone has some insight.
My goal is to pause, save to file, and restart a running thread from its exact context with no modification to that thread's code, or rather, modification in only a small area - i.e., I can't go writing serialization functions throughout the code. The main block of code must be unmodified, and will not have any global/system handles (file handles, sockets, mutexes, etc.) Really down-and-dirty details like CPU registers do not need to be saved; but basically the heap, stack, and program counter should be saved, and anything else required to get the thread running again logically correctly from its save point. The resulting state of the program should be no different, if it was saved or not.
This is for a debugging program for high-reliability software; the goal is to run simulations of the software with various scripts for input, and be able to pause a running simulation and then restart it again later - or get the sim to a branch point, save it, make lots of copies and then run further simulations from the common starting point. This is why the main program cannot be modified.
The main thread language is in C++, and should run on Windows and Linux, however if there is a way to only do this on one system, then that's acceptable too.
Thanks in advance.
I think what you're asking is much more complicated than you think. I am not too familiar with Windows programming but here are some of the difficulties you'll face in Linux.
A saved thread can only be restored from the root process that originally spawned the thread, otherwise the dynamic libraries would be broken. Because of this saving to disk is essentially meaningless. The reason is dynamic libraries are loaded at different address each time they're loaded. The only way around this would be to take complete control of dynamically linking, no small feat. It's possible, but pretty scary.
The suspended thread will have variables in the the heap. You'd need to be able to find all globals 'owned' by the thread. The 'owned' state of any piece of the heap cannot be determined. In the future it may be possible with the C++0x's garbage collection ABI. You can't just assume the whole stack belongs to the thread to be paused. The main thread uses the heap when creating threads. So blowing away the heap when deserializing the paused thread would break the main thread.
You need to address the issues with globals. And not just the globals from created in the threads. Globals (or statics) can and often are created in dynamic libraries.
There are more resources to a program than just memory. You have file handles, network sockets, database connections, etc. A file handle is just a number. serializing its memory is completely meaningless without the context of the process the file was opened in.
All that said. I don't think the core problem is impossible, just that you should consider a different approach.
Anyway to try to implement this the thread to paused needs to be in a known state. I imagine the thread to be stoped would call a library function meant the halt the process so it could be resumed.
I think the linux system call fork is your friend. Fork perfectly duplicates a process. Have the system run to the desired point and fork. One fork wait to fork others. The second fork runs one set of input.
once it completes the first fork can for again. Again the second fork can run another set of input.
continue ad infinitum.
Threads run in the context of a process. So if you want to do anything like persist a thread state to disk, you need to "hibernate" the entire process.
You will need to serialise the entire set of the processes data. And you'll need to store the current thread execution point. I think serialising the process is do-able (check out boost::serialize) but the thread stop point is a lot more difficult. I would put places where it can be stopped through the code, but as you say, you cannot modify the code.
Given that problem, you're looking at virtualising the platform the app is running on, and using its suspend functionality to pause the entire thing. You might find more information about how to do this in the virtualisation vendor's features, eg Xen.
As the whole logical address space of the program is part of the thread's context, you would have to hibernate the whole process.
If you can guarantee that the thread only uses local variables, you could save its stack. It is easy to suspend a thread with pthreads, but I don't see how you could access its stack from outside then.
The way you would have to do this is via VM Snapshots; get a copy of VMWare Workstation, then you can write code to automate starting/stopping/snapshotting the machine at different points. Any other approach is pretty untenable, as while you might be able to freeze and dethaw a process, you can't reconstruct the system state it expects (all the stuff that Caspin mentions like file handles et al.)