Need solution for parallel processing in tcl (windows).
I tried with thread, still not able to achieve desired output.
To simplify My requirement I am giving a simple example as following.
Requirement:
I want to run notepad.exe without effecting my current execution of flow. From main thread control should go to called thread, start notepad.exe and come back to main thread with out closing the notepad .
Tried:(Tcl script)
package require Thread
set a 10
proc test_thread {b} {
puts "in procedure $b"
set tid [thread::create] ;# Create a thread
return $tid
}
puts "main thread"
puts [thread::id]
set ttid [test_thread $a]
thread::send $ttid {exec c:/windows/system32/notepad.exe &}
puts "end"
Getting Output:
running notepad without showing any log.
when closing notepad application I am getting following output.
main thread
tid0000000000001214
in procedure 10
end
Desired output:
main thread
tid0000000000001214
in procedure 10
---->> control should go to thread and run notepad.exe with out effecting main thread flow.
<<-------
end
So kindly help to solve this issue and if appart from thread concept any other is there let me know.
You're using a synchronous thread::send. It's the version that is most convenient for when you want to get a value back, but it does wait. You probably should be using the asynchronous version:
thread::send -async $ttid {exec c:/windows/system32/notepad.exe &}
# ^^^^^^ This flag here is what you need to add
However it is curious that the exec call is behaving as you describe at all; the & at the end should make it effectively asynchronous anyway. Unless there's some sort of nasty interaction with how Windows is interpreting asynchronous subprocess creation in this case.
Related
perl-5.24.0 on RH7
I'd like a forked process to kill itself when it determines that it's parent dies. I've read that I can use Linux::Prctl, set_pdeathsig() to do that. But my test of this doesn't seem to work.
#!/usr/bin/env perl
use strict;
my $pid = fork();
die if not defined $pid;
if($pid == 0) {
do_forked_steps();
}
print "====PARENT===\n";
print "Hit <CR> to kill parent.\n";
my $nocare = <>;
exit;
sub do_forked_steps {
system("/home/dgauthie/PERL/sub_fork.pl");
}
And sub_fork.pl is simply...
#!/usr/bin/env perl
use strict;
use Linux::Prctl;
Linux::Prctl::set_pdeathsig(1);
sleep(300);
exit;
(I believe sending "1" tp set_pdeathsig = SIGHUP. But I also tried "9". Same results)
When I run the first script, I can see both procs using ps in another window. When I hit in the script to kill it, I can see that proc go away, but the second one, the forked process, remains.
What am I doing wrong?
You have three processes, not two, because system forks. They are:
The parent process in the parent script ($pid != 0) which waits on <> and calls exit.
The child process, created by fork in the parent script, which calls system. system forks and then waits for its child to exit before returning.
The child process created by system which execs your child script, calls prctl, and sleeps.
When you press enter, process #1 dies, but process #2 does not, and since process #2 is the parent of process #3, the PDEATHSIG is never invoked.
Changing system to exec in your first script, so that a third process isn't created, causes the PDEATHSIG to fire in your toy problem, but without more information it isn't clear if that's suitable in the "real world" version of what you're trying to do.
I am working on a script which needs to spawn an Expect process periodically (every 5 mins) to do some work. Below is the code that I have that spawns an Expect process and does some work. The main process of the script is doing some other work at all times, for example it may wait for user input, because of that I am calling this function 'spawn_expect' in a thread that keeps calling it every 5 minutes, but the issue is that the Expect is not working as expected.
If however I replace the thread with another process, that is if I fork and let one process take care of spawning Expect and the other process does the main work of the script (for example waiting at a prompt) then Expect works fine.
My question is that is it possible to have a thread spawn Expect process ? do I have to resort to using a process to do this work ? Thanks !
sub spawn_expect {
my $expect = Expect->spawn($release_config{kinit_exec});
my $position = $expect->expect(10,
[qr/Password.*: /, sub {my $fh = shift; print $fh "password\n";}],
[timeout => sub {print "Timed out";}]);
# if this function is run via a process, $position is defined, if it is run via a thread, it is not defined
...
}
Create the Expect object beforehand (not inside a thread) and pass it to a thread
my $exp = Expect->spawn( ... );
$exp->raw_pty(1);
$exp->log_stdout(0);
my ($thr) = threads->create(\&login, $exp);
my #res = $thr->join();
# ...
sub login {
my $exp = shift;
my $position = $exp->expect( ... );
# ...
}
I tested with multiple threads, where one uses Expect with a custom test script and returns the script's output to the main thread. Let me know if I should post these (short) programs.
When the Expect object is created inside a thread it fails for me, too. My guess is that in that case it can't set up its pty the way it does that normally.
Given the clarification in a comment I'd use fork for the job though.
I have a render loop that I want to run in the background so that I can control the speed of the playback loop making it animate either slow or fast. Right now I'm using sleep and calling begin and end on the CCRenderTexture in the main thread each time I want to use the sprite:
[self performSelectorOnMainThread:#selector(visit) withObject:nil waitUntilDone:YES];
- (void)visit {
[target begin];
[[self.currentLine.brush sprite] visit];
[target end];
}
This was a hack that got it working but of course makes it run very slow. calling begin and end in the background thread just causes nothing to render at all
I want to be able to call begin, do all my drawing in the background thread and then call end but everything I've tried has either done nothing or made my EAGLView flip out.
The CCRenderTexure works by redirecting the opengl output onto itself so that the drawing that gets done is saved on your sprite. This means that in a single operation you need to call begin do all your drawing and then call end.
When running on a background thread the CCDirector is making it's own draw calls in the main thread so that when you call begin and try to do multiple functions in that state the director is drawing too causing all sorts of strange errors.
end needs to be called before normal rendering operations resume.
I have a problem.
I have a VCL application using a thread. This thread does some calculations and calls a MainForm's method through Synchronize(). It all works just fine, I have a "Start" button, which creates and runs the thread and a "Stop" button which stops and frees it. No errors, no nothing.
But for some reason when I close the application and I've run the thread I get a EOSError 1400 - Invalid window handle. I've breakpointed the OnClose procedure and the only thing I do there is saving an ini file, no error in that, when I trace further (using F7), I get to the very end (Application.Run; end.), after "calling" the end. I get the error, so there is no specific line of code raising it.
I hope the question is somewhat clear and I hope it's solvable, because just ignoring the error seems a bit unclean.
Thanks inb4
ANSWER
This error occured to me when the Execute method of a thread was called, it looked like this:
procedure TRunThread.Execute;
var (...)
begin
while not Terminated do begin
(...)
MainForm.Memo1.Lines.Add('Some text'); // Even though this call worked fine during
//the application running, it caused errors on shutting the app down.
// For acccessing GUI elements, it's necessary to use Synchronize()
(...)
end;
end;
A possible reason is some unsynchronized access to GUI from the thread. You said that the thread does not do it, but without seeing the TRunThread.Execute source code that looks like the best guess.
I had the same problem, error code 5 Access is denied. This turned out to related to a thread started to test an internet connection on an embedded panel (using BeginThread). If the user exits the form (which is testing the internet connection) immediately after displaying the form, the AV occurs.
On my development PC, the internet connection test was successful...and so fast I never saw the problem! After struggling for several hours, I finally tracked it down to this thread and reproduced it by disconnecting my network cable.
The solution was straightforward: When exiting the form (eg. in the FormDestroy event) ensure the thread is definitely not running before continuing.
is it possible to execute a crystal report (TCrpe component) from a Delphi non VCL main thread when Output = toWindow?
I execute reports from a background thread, and when Output is toPrinter or toExport, everything is fine.
I know that creating forms in a
Delphi non VCL main thread generally is a
bad idea.
When a Crystal
Report is executed, and Output=toWindow, the component creates the output
window on its own. So I cannot prevent that the window is created by the background thread.
So is there a clean way to
execute the report in a background
thread, and display the result in a
cleanly created form?
Version: Crystal11VCL7
The following code does not work:
procedure TMyThread.Execute;
var
cr: TCrpe;
begin
inherited;
cr:= TCrpe.Create(nil);
cr.ReportName:= 'C:\TestReport.rpt';
cr.Output:= toWindow;
cr.WindowParent:= Form1; //This is the main form
cr.Execute;
end;
It seems like the report will be created and immediately destroyed afterwards.
When I enter a message loop right after cr.Execute (while true do Application.ProcessMessages; - which is obviously a very bad idea), the report window is shown nicely.
Any idea, how to do it right? Or is it simply not possible? Thanks!
I haven't had any experience with Crystal for many years (thank goodness) but in the absence of any other reply I would consider approaching the problem from a different angle.
What I do is let the report form be created in the main thread - because, as you've said, it's not a good idea to do the VCL stuff in the background - but I generate all report /data/ in a background thread. Once the data is loaded then the thread signals the main form (or whatever) via a windows message and the report goes and connects up to the dataset/datasource.
Initially I display a blank label over the client area of the report window with a message saying something like 'Report loading...' then once the message is received it hides the label and attaches the data. Works really well here and keeps the UI responsive.