Class: ThreadGroup

Inherits:
Object show all
Defined in:
eval.c

Overview

ThreadGroup provides a means of keeping track of a number of threads as a group. A Thread can belong to only one ThreadGroup at a time; adding a thread to a new group will remove it from any previous group.

Newly created threads belong to the same group as the thread from which they were created.

Constant Summary collapse

Default =
thgroup_default

Instance Method Summary collapse

Instance Method Details

#add(thread) ⇒ Object

Adds the given thread to this group, removing it from any other group to which it may have previously belonged.

puts "Initial group is #{ThreadGroup::Default.list}"
tg = ThreadGroup.new
t1 = Thread.new { sleep }
t2 = Thread.new { sleep }
puts "t1 is #{t1}"
puts "t2 is #{t2}"
tg.add(t1)
puts "Initial group now #{ThreadGroup::Default.list}"
puts "tg group now #{tg.list}"

produces:

Initial group is #<Thread:0x401bdf4c>
t1 is #<Thread:0x401b3c90>
t2 is #<Thread:0x401b3c18>
Initial group now #<Thread:0x401b3c18>#<Thread:0x401bdf4c>
tg group now #<Thread:0x401b3c90>


# File 'eval.c'

/*
 *  call-seq:
 *     thgrp.add(thread)   => thgrp
 *  
 *  Adds the given <em>thread</em> to this group, removing it from any other
 *  group to which it may have previously belonged.
 *     
 *     puts "Initial group is #{ThreadGroup::Default.list}"
 *     tg = ThreadGroup.new
 *     t1 = Thread.new { sleep }
 *     t2 = Thread.new { sleep }
 *     puts "t1 is #{t1}"
 *     puts "t2 is #{t2}"
 *     tg.add(t1)
 *     puts "Initial group now #{ThreadGroup::Default.list}"
 *     puts "tg group now #{tg.list}"
 *     
 *  <em>produces:</em>
 *     
 *     Initial group is #<Thread:0x401bdf4c>
 *     t1 is #<Thread:0x401b3c90>
 *     t2 is #<Thread:0x401b3c18>
 *     Initial group now #<Thread:0x401b3c18>#<Thread:0x401bdf4c>
 *     tg group now #<Thread:0x401b3c90>
 */

static VALUE
thgroup_add(group, thread)
    VALUE group, thread;
{
    rb_thread_t th;
    struct thgroup *data;

    rb_secure(4);
    th = rb_thread_check(thread);

    if (OBJ_FROZEN(group)) {
      rb_raise(rb_eThreadError, "can't move to the frozen thread group");
    }
    Data_Get_Struct(group, struct thgroup, data);
    if (data->enclosed) {
    rb_raise(rb_eThreadError, "can't move to the enclosed thread group");
    }

    if (!th->thgroup) {
    return Qnil;
    }
    if (OBJ_FROZEN(th->thgroup)) {
    rb_raise(rb_eThreadError, "can't move from the frozen thread group");
    }
    Data_Get_Struct(th->thgroup, struct thgroup, data);
    if (data->enclosed) {
    rb_raise(rb_eThreadError, "can't move from the enclosed thread group");
    }

    th->thgroup = group;
    return group;
}

#encloseObject

Prevents threads from being added to or removed from the receiving ThreadGroup. New threads can still be started in an enclosed ThreadGroup.

ThreadGroup::Default.enclose        #=> #<ThreadGroup:0x4029d914>
thr = Thread::new { Thread.stop }   #=> #<Thread:0x402a7210 sleep>
tg = ThreadGroup::new               #=> #<ThreadGroup:0x402752d4>
tg.add thr

produces:

ThreadError: can't move from the enclosed thread group


# File 'eval.c'

/*
 *  call-seq:
 *     thgrp.enclose   => thgrp
 *  
 *  Prevents threads from being added to or removed from the receiving
 *  <code>ThreadGroup</code>. New threads can still be started in an enclosed
 *  <code>ThreadGroup</code>.
 *     
 *     ThreadGroup::Default.enclose        #=> #<ThreadGroup:0x4029d914>
 *     thr = Thread::new { Thread.stop }   #=> #<Thread:0x402a7210 sleep>
 *     tg = ThreadGroup::new               #=> #<ThreadGroup:0x402752d4>
 *     tg.add thr
 *
 *  <em>produces:</em>
 *
 *     ThreadError: can't move from the enclosed thread group
 */

static VALUE
thgroup_enclose(group)
    VALUE group;
{
    struct thgroup *data;

    Data_Get_Struct(group, struct thgroup, data);
    data->enclosed = 1;

    return group;
}

#enclosed?Boolean

Returns true if thgrp is enclosed. See also ThreadGroup#enclose.

Returns:

  • (Boolean)


# File 'eval.c'

/*
 *  call-seq:
 *     thgrp.enclosed?   => true or false
 *  
 *  Returns <code>true</code> if <em>thgrp</em> is enclosed. See also
 *  ThreadGroup#enclose.
 */

static VALUE
thgroup_enclosed_p(group)
    VALUE group;
{
    struct thgroup *data;

    Data_Get_Struct(group, struct thgroup, data);
    if (data->enclosed) return Qtrue;
    return Qfalse;
}

#listArray

Returns an array of all existing Thread objects that belong to this group.

ThreadGroup::Default.list   #=> [#<Thread:0x401bdf4c run>]

Returns:



# File 'eval.c'

/*
 *  call-seq:
 *     thgrp.list   => array
 *  
 *  Returns an array of all existing <code>Thread</code> objects that belong to
 *  this group.
 *     
 *     ThreadGroup::Default.list   #=> [#<Thread:0x401bdf4c run>]
 */

static VALUE
thgroup_list(group)
    VALUE group;
{
    struct thgroup *data;
    rb_thread_t th;
    VALUE ary;

    Data_Get_Struct(group, struct thgroup, data);
    ary = rb_ary_new();

    FOREACH_THREAD(th) {
    if (th->thgroup == data->group) {
        rb_ary_push(ary, th->thread);
    }
    }
    END_FOREACH(th);

    return ary;
}