Go to file
Patrick Mahoney 9f17aac114 Modify args to Semaphore and Port constructors to accept existing ports. 2012-01-16 08:14:58 -06:00
ext/libpsem Adjust invalid tv_nsec values after adding. 2011-12-17 10:05:35 -06:00
lib Modify args to Semaphore and Port constructors to accept existing ports. 2012-01-16 08:14:58 -06:00
spec Modify args to Semaphore and Port constructors to accept existing ports. 2012-01-16 08:14:58 -06:00
.gitignore Add SimpleCov coverage when running tests under 1.9 (though it doesn't seem to measure correctly...?). 2011-12-17 21:50:12 -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 compile task as dependency of test task. 2011-12-11 21:47:16 -06:00
process_shared.gemspec Bump patch version. 2011-12-21 08:17:00 -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..