Note that the "retry loop for deleting the executable" technique has zero
wait time if the delete succeeds.

A year or so ago I submitted a bug report because I had a program that ran
hundreds of external processes (one at a time), and my Go program was way
slower that a Python program that did the same thing. Turns out that it was
because of the unconditional 5ms delay that was built into the Windows
incantation of os (Go\src\os\exec_windows.go). This is an excerpt from that
file:

   // NOTE(brainman): It seems that sometimes process is not dead
   // when WaitForSingleObject returns. But we do not know any
   // other way to wait for it. Sleeping for a while seems to do
   // the trick sometimes.
   // See https://golang.org/issue/25965 for details.
   defer time.Sleep(5 * time.Millisecond)
   defer p.Release()

Seems like a great idea to have zero delay except in those few times that
it is necessary.

On Sat, Aug 15, 2020 at 9:31 AM Bob Alexander <bobja...@gmail.com> wrote:

> Here's what I think is really going on:
>
> At the end of a process's execution, 2 things happen:
>   - The process's code finishes its execution -- wait returns.
>   - The OS closes the executable file.
>
> The second item always "comes after" the first. On Windows the delay might
> be a few milliseconds, which can cause a problem, since an attempt to
> delete the executable right after wait returns can fail because the
> executable is still open. On Unix, this is not a problem because it's OK to
> "remove" an open file -- the file doesn't actually get deleted until all
> openers have closed the file.
>
> At one time, Go's os/exec for Windows had a built-in unconditional 5ms
> delay to prevent this from happening. Not sure if it still does that.
>
> It seems that, on Windows, if a program wants to delete the executable
> right after its process has finished, if should put the delete in a little
> retry loop:
>    loop a few times (10?)
>       try do delete the executable
>       if the delete succeeds
>           exit this loop
>       wait a short time (1 ms ?)
>    announce an error -- executable could not be deleted in reasonable time
> after process completion
>
> This retry loop would be the responsibility of any Windows program that
> wants to delete the executable file after its execution finishes.
> In reality, this is not done in very many places, done only by some tools
> like "go run" (build, run, delete), and the occasional user-written tool.
> The vast majority of places where external processes are run leave the
> executable file alone after process completion.
>
> Is it the responsibility of an OS like Windows the guarantee the the
> executable is closed when a process wait returns? I would say not, because
> that might cause a (small) delay in the vast majority of external process
> executions where the executable is not deleted immediately after.
>
>
> On Friday, August 14, 2020 at 8:55:55 AM UTC-7, jake...@gmail.com wrote:
>>
>> > Turns out it takes some time to release the lock on the folder, so we
>> should do some time.Sleep before the os.Remove, so that Windows can release
>> the lock.
>>
>> I do not believe that should be the case under normal Windows operation.
>> Using a Sleep in a case like this is always a hack. Sometimes it is the
>> only way, but it can fail randomly, especially under stress. There is
>> likely something else going on. Could be poorly written antivirus software,
>> or a finalizer that has not run in your go app, or something else. If it is
>> ok for it to work "most of the time", then maybe your Sleep() solution is
>> sufficient. But if you need real reliability, I suggest figuring out what
>> is really going on.
>>
>> On Friday, August 14, 2020 at 10:10:44 AM UTC-4 atakanc...@gmail.com
>> wrote:
>>
>>> Hello guys, I have solved the issue.
>>>
>>> Turns out it takes some time to release the lock on the folder, so we
>>> should do some time.Sleep before the os.Remove, so that Windows can release
>>> the lock.
>>>
>>> Thank you both for replying.
>>>
>>> 14 Ağustos 2020 Cuma tarihinde saat 16:21:17 UTC+3 itibarıyla
>>> jake...@gmail.com şunları yazdı:
>>>
>>>> This works fine for me on Windows 10.
>>>> What is "my.exe" doing?
>>>> Do you have third party antivirus software? If so, try turning it off.
>>>> They are notorious for causing this kind of problem.
>>>>
>>>> On Friday, August 14, 2020 at 5:02:36 AM UTC-4 atakanc...@gmail.com
>>>> wrote:
>>>>
>>>>> Hello dear fellow gophers,
>>>>>
>>>>> I had a relatively simple yet quite inconvenient issue which I felt
>>>>> the need to ask here. In my main() function;
>>>>>
>>>>> os.Remove("my.exe") // err is nil, my.exe is removed
>>>>>
>>>>> works in Windows without any errors, but when I call exec beforehand,
>>>>> I get access is denied error;
>>>>>
>>>>> buffer, err := exec.Command("my.exe", myArgs...).Output() // err is
>>>>> nil here, I get desired output
>>>>> os.Remove("my.exe") // remove "C:\\.......\my.exe": Access is denied
>>>>>
>>>>> I tried using cmd.Process.Kill(), cmd.Process.Wait(),
>>>>> cmd.Start()-ioutil.ReadlAll()-cmd.Wait() alternatives as well. I kept
>>>>> getting no errors until 'Access is denied'.
>>>>>
>>>>> I'm using go1.14 linux/amd64 for my compiler and Windows 10 Enterprise
>>>>> 10.0.18362.
>>>>>
>>>>> Thank you.
>>>>>
>>>> --
> You received this message because you are subscribed to a topic in the
> Google Groups "golang-nuts" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/golang-nuts/XglcNW0USuc/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/f0a33b3f-a342-4a9a-9ccc-b0265bd2d60ao%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/f0a33b3f-a342-4a9a-9ccc-b0265bd2d60ao%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAKyHfRNgrQoD691SUy4dT06ZRJAheboRL8JZ_CqYt2sZto9t0w%40mail.gmail.com.

Reply via email to