Go to file
Patrick Mahoney 662a86f2ab Add release management rake tasks. 2012-02-09 08:14:47 -06:00
ext/helper Remove no-longer-used libpsem and related code and tests. 2012-02-01 21:42:34 -06:00
lib Refactor Mach FFI wrapper; get unit tests working again. 2012-02-08 21:30:18 -06:00
spec Revert debugging change to unit test. 2012-02-08 21:29:37 -06:00
.gitignore Add doc, others to gitignore. 2012-02-01 19:39:26 -06:00
COPYING Initial commit. 2011-12-11 21:39:55 -06:00
ChangeLog Initial commit. 2011-12-11 21:39:55 -06:00
Gemfile Initial commit. 2011-12-11 21:39:55 -06:00
README.rdoc Add object transfer example to README. 2011-12-20 22:16:50 -06:00
Rakefile Add release management rake tasks. 2012-02-09 08:14:47 -06:00
VERSION Version bump to 0.1.6a 2012-02-09 08:14:03 -06:00
process_shared.gemspec Add release management rake tasks. 2012-02-09 08:14:47 -06:00

README.rdoc

== Description

Concurrency primitives that may be used in a cross-process way to
coordinate share memory between processes.

A small C library (libpsem) is compiled to provide portable access to
semaphores (based on http://pyprocessing.berlios.de/).  This library
is then accessed using FFI to implement Ruby classes
ProcessShared::Semaphore, ProcessShared::BoundedSemaphore,
ProcessShared::Mutex, and ProcessShared::SharedMemory.

This is an incomplete work in progress.

== License

MIT

== Install
Install the gem with:

    gem install process_shared

== Usage

    require 'process_shared'

    mutex = ProcessShared::Mutex.new
    mem = ProcessShared::SharedMemory.new(:int)  # extends FFI::Pointer
    mem.put_int(0, 0)

    pid1 = fork do
      puts "in process 1 (#{Process.pid})"
      10.times do
        sleep 0.01
        mutex.synchronize do
          value = mem.get_int(0)
          sleep 0.01
          puts "process 1 (#{Process.pid}) incrementing"
          mem.put_int(0, value + 1)
        end
      end
    end

    pid2 = fork do
      puts "in process 2 (#{Process.pid})"
      10.times do
        sleep 0.01
        mutex.synchronize do
          value = mem.get_int(0)
          sleep 0.01
          puts "process 2 (#{Process.pid}) decrementing"
          mem.put_int(0, value - 1)
        end
      end
    end

    Process.wait(pid1)
    Process.wait(pid2)

    puts "value should be zero: #{mem.get_int(0)}"

== Transfer Objects Across Processes

    # allocate a sufficient memory block
    mem = ProcessShared::SharedMemory.new(1024)

    # sub process can write (serialize) object to memory (with bounds checking)
    pid = fork do
      mem.write_object(['a', 'b'])
    end

    Process.wait(pid)

    # parent process can read the object back (synchronizing access
    # with a Mutex left as an excercie to reader)

    mem.read_object.must_equal ['a', 'b']

== Todo

* Test ConditionVariable
* Implement optional override of core Thread/Mutex classes
* Extend libpsem to win32?  (See Python's processing library)
* Break out tests that use PSem.getvalue() (which isn't supported on Mac OS X)
  so that the test suite will pass
* Add finalizer to Mutex? (finalizer on Semaphore objects may be enough) or a method to
  explicitly close and release resources?
* Test semantics of crashing processes who still hold locks, etc.
* Is SharedArray with Enumerable mixing sufficient Array-like interface?
* Remove bsem from libpsem as it is of little use and doesn't work on Mac OS X
* Possibly implement BoundedSemaphore with arbitrary bound (in Ruby
  rather than relying on sem_getvalue()), but this is of little
  utility beyond extra error checking..