FAQ
I maintain goncurses[1] and I am appealing to those of who who would be
better at concurrency than myself. Almost every function in the curses
library reads or writes to the underlying C data structures. Curses, and
its more modern descendants, were not built with concurrency in mind.
ncurses has added some built-in functions which can be used to wrap any
other function in the library with a global lock/mutex but from research
I've done it's not recommended to use/rely on them as there is still the
potential for race conditions/data corruption (I'm not exactly sure why).

Thus, I've had two options:

1) Wrap every function in a global mutex (well over 100).
2) Instruct users to wrap any curses functions within some kind of
synchronization (channel or mutex) to ensure no curses functions are ever
called concurrently.

I have opted, so far, to take option 2 and do so in my own code. I am
worried that wrapping certain functions, especially those which are
blocking (buffered input comes to mind), will cause bottlenecks/deadlocks.
Is my reasoning sound? Is there a better way I should be handling this?

[1] http://code.google.com/p/goncurses

--
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • RickyS at Nov 16, 2013 at 10:49 pm
    What could you do concurrently or in parallel, since the codebase is still
    'single-threaded'?
    That is, could curses start prompting the user for input while it draws the
    screen? Or something?
    I would guess there is nothing you could do that was correct and reliable.
    In my memory the old thing would have to wait until the i/o was done,
    anyway.

    Perhaps you could reject any call that was not from the starting thread?
    I guess the best is provide help for item 2).

    Are there startups basing their product on ncurses?
    It was designed originally for the vt100, hardware from 30 years ago. The
    software is older than you (probably) are.
    Best of luck.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Rob Thornton at Nov 16, 2013 at 11:06 pm
    I know of its use in a few games. It would be natural for game related
    events and drawing to the screen to be handled separately in a goroutine
    and input in another.

    Amusingly, the closest date I could find for the initial release of curses
    was "around 1980" which makes me only slightly older than the library. ;)
    On Saturday, 16 November 2013 14:49:54 UTC-8, RickyS wrote:

    What could you do concurrently or in parallel, since the codebase is still
    'single-threaded'?
    That is, could curses start prompting the user for input while it draws
    the screen? Or something?
    I would guess there is nothing you could do that was correct and reliable.
    In my memory the old thing would have to wait until the i/o was done,
    anyway.

    Perhaps you could reject any call that was not from the starting thread?
    I guess the best is provide help for item 2).

    Are there startups basing their product on ncurses?
    It was designed originally for the vt100, hardware from 30 years ago. The
    software is older than you (probably) are.
    Best of luck.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Jesse van den Kieboom at Nov 17, 2013 at 8:14 am
    I only have experience with gtk+ so I'm no authority, but. All gui
    libraries that I know are not made to be thread safe, but should be called
    from the same thread it was initialized from. This works well if you
    instruct users about it properly because in most languages you control
    threads explicitly and you know how to synchronize between them. In gtk+
    (and I see something similar in the go qml bindings) you usually install a
    callback which is called when the gui main loop gets idle. The callback is
    executed in the context of the main loop.

    The thing with go is that threads can be created all the time and you don't
    even know it. go routines are such an integral part of the language, that I
    as a user would expected that gui libraries take care of allowing me to
    call their code from multiple go routines. You can
    check https://github.com/niemeyer/qml to see how you can do that in a
    relatively nice way without locking all the time.
    On Sunday, November 17, 2013 12:06:19 AM UTC+1, Rob Thornton wrote:

    I know of its use in a few games. It would be natural for game related
    events and drawing to the screen to be handled separately in a goroutine
    and input in another.

    Amusingly, the closest date I could find for the initial release of curses
    was "around 1980" which makes me only slightly older than the library. ;)
    On Saturday, 16 November 2013 14:49:54 UTC-8, RickyS wrote:

    What could you do concurrently or in parallel, since the codebase is
    still 'single-threaded'?
    That is, could curses start prompting the user for input while it draws
    the screen? Or something?
    I would guess there is nothing you could do that was correct and reliable.
    In my memory the old thing would have to wait until the i/o was done,
    anyway.

    Perhaps you could reject any call that was not from the starting thread?
    I guess the best is provide help for item 2).

    Are there startups basing their product on ncurses?
    It was designed originally for the vt100, hardware from 30 years ago.
    The software is older than you (probably) are.
    Best of luck.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Jsor at Nov 19, 2013 at 11:30 pm
    The way I solved OpenGL in a multi-threaded, concurrent environment was to
    have a "master" goroutine that formally owned the context, and was
    perpetually locked in a loop over a chan func(). While you can do any
    calculations or whathaveyou outside the thread/goroutine, to execute
    instructions on the context itself, you send a func() over a channel to the
    main context, and the context thread will execute it. A simple/naive
    implementation is just

    runtime.LockOSThread()
    whateverImUsing.MakeContextCurrent()

    for f := range instructionChan {
         f()
    }

    Though often you need a bit more control than that (my rendering system
    uses a select statement that is set to render the scene at set intervals
    between executing functions, for instance), but the gist remains the same.

    You do have to be aware that instructions may not be executed immediately,
    of course, but it works pretty well and the delay in execution is usually
    fairly negligible (at the very least it's not too much worse than any OTHER
    non-professional implementation of an asynchronous rendering system).

    You may want to handle I/O separately, but with most setups it's not
    strictly possible (the event callbacks for the input are going to be
    executed in the context no matter what), but you can keep them conceptually
    separate if you introduce a one-way dependency. For instance, I have an
    input handler that tags along with my renderer as a separate subsystem, and
    reading the code it feels like they're mostly independent of each other,
    but in reality 90% of the "input handler's" job is feeding new callback
    registration requests to the renderer's function channel as is necessary.
    Most of the actual work is executed in the renderer's thread/goroutine even
    though the code is in the input handler. (And the rendering system is
    agnostic to the input handler's existence).

    I don't know how much of this is immediately applicable to ncurses, or
    gtk+, or whatever else, but from the gist I got from the thread they seem
    similar in concept.

    I'm sure it may be theoretically possible to do I/O concurrently, but it
    would probably have to be built ground-up with it in mind, not just a
    wrapper around an existing library. Rob wrote an article on a concurrent
    window system here: http://swtch.com/~rsc/thread/cws.pdf
    On Sunday, November 17, 2013 1:14:40 AM UTC-7, Jesse van den Kieboom wrote:

    I only have experience with gtk+ so I'm no authority, but. All gui
    libraries that I know are not made to be thread safe, but should be called
    from the same thread it was initialized from. This works well if you
    instruct users about it properly because in most languages you control
    threads explicitly and you know how to synchronize between them. In gtk+
    (and I see something similar in the go qml bindings) you usually install a
    callback which is called when the gui main loop gets idle. The callback is
    executed in the context of the main loop.

    The thing with go is that threads can be created all the time and you
    don't even know it. go routines are such an integral part of the language,
    that I as a user would expected that gui libraries take care of allowing me
    to call their code from multiple go routines. You can check
    https://github.com/niemeyer/qml to see how you can do that in a
    relatively nice way without locking all the time.
    On Sunday, November 17, 2013 12:06:19 AM UTC+1, Rob Thornton wrote:

    I know of its use in a few games. It would be natural for game related
    events and drawing to the screen to be handled separately in a goroutine
    and input in another.

    Amusingly, the closest date I could find for the initial release of
    curses was "around 1980" which makes me only slightly older than the
    library. ;)
    On Saturday, 16 November 2013 14:49:54 UTC-8, RickyS wrote:

    What could you do concurrently or in parallel, since the codebase is
    still 'single-threaded'?
    That is, could curses start prompting the user for input while it draws
    the screen? Or something?
    I would guess there is nothing you could do that was correct and
    reliable.
    In my memory the old thing would have to wait until the i/o was done,
    anyway.

    Perhaps you could reject any call that was not from the starting thread?
    I guess the best is provide help for item 2).

    Are there startups basing their product on ncurses?
    It was designed originally for the vt100, hardware from 30 years ago.
    The software is older than you (probably) are.
    Best of luck.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Rob Thornton at Nov 20, 2013 at 4:09 pm
    Thanks for your input Jsor. I would certainly draw a closer parallel from
    curses to OpenGL than a GUI toolkit. NTK, the Ncurses ToolKit, would be
    more like Gtk+ in it's scope. Your solution is intriguing and I'll take a
    closer look at it.

    On Tue, Nov 19, 2013 at 3:29 PM, Jsor wrote:

    The way I solved OpenGL in a multi-threaded, concurrent environment was to
    have a "master" goroutine that formally owned the context, and was
    perpetually locked in a loop over a chan func(). While you can do any
    calculations or whathaveyou outside the thread/goroutine, to execute
    instructions on the context itself, you send a func() over a channel to the
    main context, and the context thread will execute it. A simple/naive
    implementation is just

    runtime.LockOSThread()
    whateverImUsing.MakeContextCurrent()

    for f := range instructionChan {
    f()
    }

    Though often you need a bit more control than that (my rendering system
    uses a select statement that is set to render the scene at set intervals
    between executing functions, for instance), but the gist remains the same.

    You do have to be aware that instructions may not be executed immediately,
    of course, but it works pretty well and the delay in execution is usually
    fairly negligible (at the very least it's not too much worse than any OTHER
    non-professional implementation of an asynchronous rendering system).

    You may want to handle I/O separately, but with most setups it's not
    strictly possible (the event callbacks for the input are going to be
    executed in the context no matter what), but you can keep them conceptually
    separate if you introduce a one-way dependency. For instance, I have an
    input handler that tags along with my renderer as a separate subsystem, and
    reading the code it feels like they're mostly independent of each other,
    but in reality 90% of the "input handler's" job is feeding new callback
    registration requests to the renderer's function channel as is necessary.
    Most of the actual work is executed in the renderer's thread/goroutine even
    though the code is in the input handler. (And the rendering system is
    agnostic to the input handler's existence).

    I don't know how much of this is immediately applicable to ncurses, or
    gtk+, or whatever else, but from the gist I got from the thread they seem
    similar in concept.

    I'm sure it may be theoretically possible to do I/O concurrently, but it
    would probably have to be built ground-up with it in mind, not just a
    wrapper around an existing library. Rob wrote an article on a concurrent
    window system here: http://swtch.com/~rsc/thread/cws.pdf

    On Sunday, November 17, 2013 1:14:40 AM UTC-7, Jesse van den Kieboom wrote:

    I only have experience with gtk+ so I'm no authority, but. All gui
    libraries that I know are not made to be thread safe, but should be called
    from the same thread it was initialized from. This works well if you
    instruct users about it properly because in most languages you control
    threads explicitly and you know how to synchronize between them. In gtk+
    (and I see something similar in the go qml bindings) you usually install a
    callback which is called when the gui main loop gets idle. The callback is
    executed in the context of the main loop.

    The thing with go is that threads can be created all the time and you
    don't even know it. go routines are such an integral part of the language,
    that I as a user would expected that gui libraries take care of allowing me
    to call their code from multiple go routines. You can check
    https://github.com/niemeyer/qml to see how you can do that in a
    relatively nice way without locking all the time.
    On Sunday, November 17, 2013 12:06:19 AM UTC+1, Rob Thornton wrote:

    I know of its use in a few games. It would be natural for game related
    events and drawing to the screen to be handled separately in a goroutine
    and input in another.

    Amusingly, the closest date I could find for the initial release of
    curses was "around 1980" which makes me only slightly older than the
    library. ;)
    On Saturday, 16 November 2013 14:49:54 UTC-8, RickyS wrote:

    What could you do concurrently or in parallel, since the codebase is
    still 'single-threaded'?
    That is, could curses start prompting the user for input while it draws
    the screen? Or something?
    I would guess there is nothing you could do that was correct and
    reliable.
    In my memory the old thing would have to wait until the i/o was done,
    anyway.

    Perhaps you could reject any call that was not from the starting thread?
    I guess the best is provide help for item 2).

    Are there startups basing their product on ncurses?
    It was designed originally for the vt100, hardware from 30 years ago.
    The software is older than you (probably) are.
    Best of luck.
    --
    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/q0bYe7CA_y4/unsubscribe.
    To unsubscribe from this group and all its topics, send an email to
    golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedNov 16, '13 at 10:34p
activeNov 20, '13 at 4:09p
posts6
users4
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase