Issue #6694 has been updated by Koichi Sasada.


Existing Ideas:

* (1) allow keywords for `new()` (like `new(name: "worker-thread")`)
** (1-1) introducing it immediately and break compatibility
** (1-2) introducing it and introduce proper keyword semantics (I doubt we can close this discussion) 
* (2) create threads by `new()` without block
* (2-1) provide `proc:` keyword [Feature #6694]
* (2-2) suspend thread and configure it before running https://bugs.ruby-lang.org/issues/3187#note-10
** (3) Make builders (templates) with specific parameters https://bugs.ruby-lang.org/issues/3187#note-8

Simple one is (1-1), but it can introduce compatibility issue.
Of course, I'm not sure how affect this incompatibility, but `csearch Thread.new\\\( | grep 'name:'` doesn't match on all of gems.
(`name:` is only one property so it is not right example)

----------------------------------------
Feature #6694: Thread.new without block.
https://bugs.ruby-lang.org/issues/6694#change-62757

* Author: Koichi Sasada
* Status: Assigned
* Priority: Normal
* Assignee: Koichi Sasada
* Target version: next minor
----------------------------------------
# Abstract

Support Thread.new() without block.

Before: `Thread.new(params...){|thread_local_params| ...}`

After: `Thread.new(proc: lambda{|tl_params...| ...}, args: params..., other_thread_config...)`

# Background

Thread.new creates new Thread object and run passed block in another thread immediately.  Thread.new can receive parameters and pass all parameters to block.

```
  Thread.new(a, b, c) do |ta, tb, tc|
    # ta, tb, tc is thread local
  }
```

There are some request to specify thread configurations such as stack size described in [Ruby 1.9 - Feature #3187] (in this case, stack size for Fiber.new).  However, we have no way to pass such thread configuration on the Thread.new().

# Proposal

Allow Thread.new() without block.  A block will be passed with proc parameter.  Passed arguments will be passed with args parameter.

```
  # ex1
  Thread.new(){...}
  #=>
  Thread.new(proc: -> {...})
  
  # ex2
  Thread.new(a, b, c){|ta, tb, tc| ...}
  #=>
  Thread.new(proc: ->(ta, tb, tc){ ... }, params: [a, b, c])
```

If you want to specify stack size, then:

  Thread.new(stack_size: 4096, proc: proc{...}, args: [a, b, c])

Note that I'll make another ticket for thread (and fiber) creation parameters.

This change can be described with the following pseudo code:

```
  def Thread.new(*args, &block)
    if block
      Thread.new_orig(*args, &block)
    else
      config = args[0] || raise ArgumentError
      stack_size = config[:stack_size]
      # ... and process another parameters 
      Thread.new_orig(*config[:args], &config[:proc])
    end
  end
```

# Another proposal

On the [ruby-core:43385], Nahi-san proposed that if no block given on Thread.new(), then create "waiting" thread.  Thread#run kicks waiting thread with parameters.

```
  th = Thread.new(thread_config_params)
  ...
  th.run(params){|thread_local_params|
    ...
  }
```

We can combine with `proc:` parameter and this proposal.
If `Thread.new()` doesn't have block and `proc:` parameter, then making a waiting thread.

NOTE: Because we have already Thread#run, Thread#start is better than Thread#run?

# Note

I don't make any survey on other languages.  Please give us your comments.





-- 
https://bugs.ruby-lang.org/