I am spawning a process using D's std.process.pipeProcess function, which gives me std.stdio.File structs for the process's input and output respectively. I need to be able to process output from the process, while at the same time process input from my own console.
Since there is no way to do a non-blocking readln() on a File struct, I need to spawn another thread to do a blocking wait for me, and then message pass it to the main thread via std.concurrency.
My problem is that when I pass it like this:
spawn(&myConsoleListenFunction, pipe.stdout)
The compiler says that that "Aliases to mutable thread-local data are not allowed". I know that means that I need to cast to shared, but I can't do that either because when I try to cast the File to shared I get this:
C:\D\dmd2\windows\bin\..\..\src\phobos\std\concurrency.d(487,5): Error: non-shared method std.stdio.File.~this is not callable using a shared object
source\app.d(67,26): Error: template std.concurrency.spawn cannot deduce function from argument types !()(void function(File f, string prefix), shared(File), string), candidates are:
C:\D\dmd2\windows\bin\..\..\src\phobos\std\concurrency.d(487,5): std.concurrency.spawn(F, T...)(F fn, T args) if (isSpawnable!(F, T))
I also tried passing the File as __gshared, which results in the same "Alias" message.
Related
In C++/C#/Java we can start the thread with function that accepts some arguments. In WinAPI we start the thread with function that accepts only void*.
How many arguments are passed really to real windows threads? Maybe many arguments are turned into void* that points on some struct?
At the core of most threading APIs is a function pointer to execute and a void* parameter that lets you provide some data to the executing function. The void* typically points to some object instance that the thread function then casts into the known object type to use. This, however, is ripe for programmer error.
The higher level APIs that you mention (std::thread in C++, Thread in Java, etc) are doing this under the hood and providing you convenient, type-safe APIs to ensure you can't mess it up.
Java docs state following regarding synchronization of constructor:
Note that constructors cannot be synchronized — using the synchronized keyword with a constructor is a syntax error. Synchronizing constructors doesn't make sense, because only the thread that creates an object should have access to it while it is being constructed.
Warning: When constructing an object that will be shared between
threads, be very careful that a reference to the object does not
"leak" prematurely. For example, suppose you want to maintain a List
called instances containing every instance of class. You might be
tempted to add the following line to your constructor:
instances.add(this); But then other threads can use instances to
access the object before construction of the object is complete.
I am not able to understand this whole block. First it states that only the thread that creates an object has access to constructor. Then it warns of premature leak which may cause issues if other threads access the object before construction is complete. Are not these two things in contradiction. If only the creating thread can access the constructor then how can other threads prematurely access the object as it can only be accessed once contructor has run fully?
Any input would be of great help.
Imagine two threads that both have access to a global List (called "instances") holding instances of the class in question. Thread 1 continuously cycles through the list and does something with each instance. Thread 2 goes its own merry way, and occasionally constructs a new instance of the class. If the class would add itself to the List in its constructor (using instances.add(this)) Thread 1 would immediately get access to the instance and could do things with it before it is fully constructed, resulting in unpredictable behavior.
There may be a misunderstanding of the word "should". You wrote: "First it states that only the thread that creates an object has access to constructor. " However, the Java docs say: "only the thread that creates an object should have access to it while it is being constructed", which means that you should take care that only one thread has access to the object while it is being constructed.
I am using groovy scripting execution in multi threaded mode.
Script themselves are thread safe.
Its like below:
//Startup Code. Single threaded
Class<?> scriptClass = getScriptClass(fileName); //utility to get script class from file name
Method method = getMethods(scriptClass); //Utility to get a specific Method
storeMethod(method); //Store method globally.
Object scriptInstance = scriptClass.newInstance();
storeScriptInstance(scriptInstance); //Store script Instance
Multiple threads execute following code: (without any synchronization.)
ScriptInstance scriptInstance = getScriptInstance(); //Utility to get scriptInstance stored in init
Method method = getMethod(); //Utility for getting method stored in init step
Object obj[] = new Object[] { context }; //context variable available per thread.
method.invoke(scriptInstance,obj);
script consists of just one function which is totally thread safe (function is reentrant and modifies context variable.)
This works in my unit testing with multiple threads but couldn't find any material to support this claim.
Question => Is it safe under multiple thread execution? More generically, sharing of same script instances across threads to execute scripts functions which themselves are thread safe is safe? Script instances shouldn't have global variables in execution.
Context is an argument to script and not global variable.
Please help.
Without the actual function I cannot tell if this is supposed to be threadsafe or not. Since you say that the function modifies the context variable I conclude that you mutate global state. In that case it is not threadsafe without synchronization of some kind. If my assumption is wrong and no global state is mutated, then executing a method by reflection is surely not the problem
When I create a new thread in a program... in it's thread handle function, why do I pass variables that I want that thread to use through the thread function prototype as parameters (as a void pointer)? Since threads share the same memory segments (except for stack) as the main program, shouldn't I be able to just use the variables directly instead of passing parameters from main program to new thread?
Well, yes, you could use the variables directly. Maybe. Assuming that they aren't changed by some other thread before your thread starts running.
Also, a big part of passing parameters to functions (including thread functions) is to limit the amount of information the called function has to know about the outside world. If you pass the thread function everything it needs in order to do its work, then you can change the rest of the program with relative impunity and the thread will still continue to work. If, however, you force the thread to know that there is a global list of strings called MyStringList, then you can't change that global list without also affecting the thread.
Information hiding. Encapsulation. Separation of concerns. Etc.
You cannot pass parameters to a thread function in any kind of normal register/stack manner because thread functions are not called by the creating thread - they are given execution directly by the underlying OS and the API's that do this copy a fixed number of parameters, (usually only one void pointer), to the new and different stack of the new thread.
As Jim says, failure to understand this mechanism often results in disaster. There are numnerous questions on SO where the vars that devs. hope would be used by a new thread are RAII'd away before the new thread even starts.
I have a system that is multi-threaded. I want to create a object in a thread, and every object that runs in this thread can view this object.
Example,
When i use GetCurrentThreadID i always get same id, if i call it from the same thread.
I want to call, for example, getSharedObject and always see the same object if i call it from the same object. So I need to write this object in a memory location that any object inside the same thread can see this object.
Is there anyway to do that, using the Windows API? Or I have to do it by myself?
thanks!
If the variable where you save the object pointer is global, then any code in your thread can access it. And any code from any other thread can, too, for that matter.
If you want that each thread sees a different object, then you want Thread Local Storage.
See the win32 functions TlsAlloc, TlsSetValue, TlsGetValue and TlsFree.
See also __declspec( thread ) here.