Tomas,

Thanks for your feedback! I couldn't find a package that handles this
already. If this technique proves to work reliably in Gaston, I'll be happy
to put it in a package.

Regarding `readnow`, I never rebind it. It doesn't hold any actual value;
it is just a `Condition()`, which can be used to notify asynchronous tasks.
I followed your advice and made it a `const`.

The other global variables actually hold data, which changes according to
the values read from the different streams. Inspired by the wrapper idea, I
wrapped them in a type so that it becomes clear that they are always
strings; hopefully this will help with performance.

The latest version of the code is at
https://gist.github.com/mbaz/bb7e2cbaaecc031b1d88

-- mb

On Mon, Jan 11, 2016 at 9:05 AM, Tomas Lycken <[email protected]>
wrote:

> Interesting question! If you find a good approach to do this, wrapping it
> in a package is certainly interesting (have you checked that there aren’t
> any packages that handle this already?).
>
> I can’t help much with the threading stuff, but regarding your global
> variable it should be possible to work around the slowness of that. I don’t
> know how, or when, you re-bind readnow, but there are two ways to fix it
> depending on the specifics:
>
>    1.
>
>    You never rebind readnow, just mutate it. Mark it const, and it’s
>    fast. (const means *impossible to rebind*, not *impossible to mutate*)
>    2.
>
>    You rebind readnow, and Condition() is mutable: Mark it const and
>    mutate it instead of rebinding.
>    3.
>
>    You rebind readnow and Condition() is immutable: Wrap the Condition in
>    a mutable type, which you assign to const readnow instead, and then
>    rebind the field in this mutable type. Something like this:
>
> type ConditionWrapper
>     c::Condition
> end
>
> const readnow = ConditionWrapper(Condition())
>
> # where you update:
> readnow.c = Condition(args...)
>
> This all assumes that Condition is an immutable concrete type, and you
> just want to switch it out for an instance with other field values. If you
> actually need to change the *type* of readnow, all bets are off and this
> trick won’t work.
>
> // T
>
> On Friday, January 8, 2016 at 9:28:02 PM UTC+1, Miguel Bazdresch wrote:
>
> Hello,
>>
>> I'd be grateful if you could take a look at some code and suggest
>> improvements.
>>
>> I'm trying to interact with a long-lived process (gnuplot). This process
>> reads commands from its STDIN; after each command is executed, it produces
>> output on either its STDOUT or STDERR. It's impossible to predict ahead of
>> time which of the two streams will be used.
>>
>> To simplify my tests, I wrote an "echo server" in C, which reads a
>> character from its STDIN and outputs it again over either STDOUT or STDERR.
>> The code is here: https://gist.github.com/mbaz/1e242694a9c4f1eca576
>>
>> Then I wrote a julia program that reads a character from its own STDIN,
>> sends it to the C echo server, and then tries to read the server's STDOUT
>> and STDERR until it finds a character. The code is here:
>> https://gist.github.com/mbaz/bb7e2cbaaecc031b1d88
>>
>> This code works, but I don't know if it is the best approach. Two
>> specific questions I have:
>>
>> * Is my `popen3()` function necessary? This closed issue seems to suggest
>> it's not, but I can't figure out how to accomplish what I need in a more
>> simple manner: https://github.com/JuliaLang/julia/issues/11824
>>
>> * Are global variables required to share data with asynchronous tasks?
>> Since global variables are slow, this approach may produce undesired code
>> slowdowns.
>>
>> Thanks,
>>
>> -- mb
>>
> ​
>

Reply via email to