Skip to content

Commit

Permalink
doc corrections to #19841 (#20010)
Browse files Browse the repository at this point in the history
* doc corrections to #19841
  • Loading branch information
amitmurthy authored Jan 13, 2017
1 parent ff9a949 commit fd14951
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 31 deletions.
2 changes: 1 addition & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ Deprecated or removed
functions (`airyai`, `airybi`, `airyaiprime`, `airybiprimex`, `airyaix`, `airybix`,
`airyaiprimex`, `airybiprimex`) ([#18050]).

* `produce`, `consume` and iteration over a Task object has been deprecated in favor of
* `produce`, `consume` and iteration over a Task object have been deprecated in favor of
using Channels for inter-task communication ([#19841]).

Julia v0.5.0 Release Notes
Expand Down
29 changes: 14 additions & 15 deletions base/channels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Channel(sz) = Channel{Any}(sz)
Channel(func::Function; ctype=Any, csize=0, taskref=nothing)
Creates a new task from `func`, binds it to a new channel of type
`ctype` and size `csize`, schedules the task, all in a single call.
`ctype` and size `csize`, and schedules the task, all in a single call.
`func` must accept the bound channel as its only argument.
Expand All @@ -71,8 +71,8 @@ Returns a Channel.
```jldoctest
julia> chnl = Channel(c->foreach(i->put!(c,i), 1:4));
julia> @show typeof(chnl);
typeof(chnl) = Channel{Any}
julia> typeof(chnl)
Channel{Any}
julia> for i in chnl
@show i
Expand All @@ -91,16 +91,14 @@ julia> taskref = Ref{Task}();
julia> chnl = Channel(c->(@show take!(c)); taskref=taskref);
julia> task = taskref[];
julia> @show istaskdone(task);
istaskdone(task) = false
julia> istaskdone(taskref[])
false
julia> put!(chnl, "Hello");
take!(c) = "Hello"
julia> @show istaskdone(task);
istaskdone(task) = true
julia> istaskdone(taskref[])
true
```
"""
Expand All @@ -111,7 +109,7 @@ function Channel(func::Function; ctype=Any, csize=0, taskref=nothing)
schedule(task)
yield()

isa(taskref, Ref{Task}) && (taskref.x = task)
isa(taskref, Ref{Task}) && (taskref[] = task)
return chnl
end

Expand Down Expand Up @@ -158,7 +156,7 @@ Terminating tasks have no effect on already closed Channel objects.
When a channel is bound to multiple tasks, the first task to terminate will
close the channel. When multiple channels are bound to the same task,
termination of the task will close all channels.
termination of the task will close all of the bound channels.
```jldoctest
julia> c = Channel(0);
Expand All @@ -175,8 +173,8 @@ i = 2
i = 3
i = 4
julia> @show isopen(c);
isopen(c) = false
julia> isopen(c)
false
```
Expand All @@ -187,7 +185,8 @@ julia> task = @schedule (put!(c,1);error("foo"));
julia> bind(c,task);
julia> take!(c);
julia> take!(c)
1
julia> put!(c,1);
ERROR: foo
Expand Down Expand Up @@ -223,7 +222,7 @@ function channeled_tasks(n::Int, funcs...; ctypes=fill(Any,n), csizes=fill(0,n))

# bind all tasks to all channels and schedule them
foreach(t -> foreach(c -> bind(c,t), chnls), tasks)
foreach(t->schedule(t), tasks)
foreach(schedule, tasks)

yield() # Allow scheduled tasks to run

Expand Down
2 changes: 2 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1625,6 +1625,7 @@ function produce(v)
end
end
produce(v...) = produce(v)
export produce

function consume(P::Task, values...)
depwarn("consume is now deprecated. Use Channels for inter-task communication.", :consume)
Expand Down Expand Up @@ -1655,6 +1656,7 @@ function consume(P::Task, values...)

P.state == :runnable ? schedule_and_wait(P) : wait() # don't attempt to queue it twice
end
export consume

function start(t::Task)
depwarn(string("Task iteration is now deprecated.",
Expand Down
2 changes: 0 additions & 2 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -954,14 +954,12 @@ export

# tasks and conditions
Condition,
consume,
current_task,
islocked,
istaskdone,
istaskstarted,
lock,
notify,
produce,
ReentrantLock,
schedule,
task_local_storage,
Expand Down
15 changes: 6 additions & 9 deletions doc/src/manual/control-flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -846,22 +846,19 @@ Julia provides a [`Channel`](@ref) mechanism for solving this problem.
A [`Channel`](@ref) is a waitable FIFO queue which can have multiple tasks reading and writing to it.

Let's define a producer task, which produces values via the [`put!`](@ref) call.
To consume values, we need to schedule the producer to run in a new task. A special [`Channel`](@ref)
constructor which accepts a 1-arg function as an argument can be used to run a task bound to a channel.
We can then [`take!()`](@ref) values repeatedly from the channel object:

```julia
```jldoctest
julia> function producer(c::Channel)
put!(c, "start")
for n=1:4
put!(c, 2n)
end
put!(c, "stop")
end;
```
To consume values, we need to schedule the producer to run in a new task. A special [`Channel`](@ref)
constructor which accepts a 1-arg function as an argument can be used to run a task bound to a channel.
We can then [`take!()`](@ref) values repeatedly from the channel object:

```jldoctest
julia> chnl = Channel(producer);
julia> take!(chnl)
Expand Down Expand Up @@ -901,7 +898,7 @@ start
stop
```

Note that we did not have to explcitly close the channel in the producer. This is because
Note that we did not have to explicitly close the channel in the producer. This is because
the act of binding a [`Channel`](@ref) to a [`Task()`](@ref) associates the open lifetime of
a channel with that of the bound task. The channel object is closed automatically when the task
terminates. Multiple channels can be bound to a task, and vice-versa.
Expand Down Expand Up @@ -944,7 +941,7 @@ this might be. If you switch away from the current task, you will probably want
to it at some point, but knowing when to switch back, and knowing which task has the responsibility
of switching back, can require considerable coordination. For example, [`put!()`](@ref) and [`take!()`](@ref)
are blocking operations, which, when used in the context of channels maintain state to remember
who the consumers is. Not needing to manually keep track of the consuming task is what makes [`put!()`](@ref)
who the consumers are. Not needing to manually keep track of the consuming task is what makes [`put!()`](@ref)
easier to use than the low-level [`yieldto()`](@ref).

In addition to [`yieldto()`](@ref), a few other basic functions are needed to use tasks effectively.
Expand Down
8 changes: 4 additions & 4 deletions test/channels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,13 @@ for N in [0,10]
@test_throws ErrorException fetch(cs[i])
end

# Multiple tasks, first one to terminate, closes the channel
# Multiple tasks, first one to terminate closes the channel
nth = rand(1:5)
ref = Ref(0)
cond = Condition()
tf3(i) = begin
if i == nth
ref.x = i
ref[] = i
else
sleep(2.0)
end
Expand All @@ -130,10 +130,10 @@ for N in [0,10]
tasks = [Task(()->tf3(i)) for i in 1:5]
c = Channel(N)
foreach(t->bind(c,t), tasks)
foreach(t->schedule(t), tasks)
foreach(schedule, tasks)
@test_throws InvalidStateException wait(c)
@test !isopen(c)
@test ref.x == nth
@test ref[] == nth

# channeled_tasks
for T in [Any, Int]
Expand Down

0 comments on commit fd14951

Please sign in to comment.