Just another update

This commit is contained in:
Ingy döt Net 2015-02-20 00:35:01 -05:00
parent a25938f123
commit 00a190b0a6
6591 changed files with 94363 additions and 23227 deletions

View file

@ -0,0 +1,42 @@
using System;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using System.IO;
namespace SynchronousConcurrency
{
class Program
{
static void Main(string[] args)
{
BlockingCollection<string> toWriterTask = new BlockingCollection<string>();
BlockingCollection<int> fromWriterTask = new BlockingCollection<int>();
Task writer = Task.Factory.StartNew(() => ConsoleWriter(toWriterTask, fromWriterTask));
Task reader = Task.Factory.StartNew(() => FileReader(fromWriterTask, toWriterTask));
Task.WaitAll(writer, reader);
}
static void ConsoleWriter(BlockingCollection<string> input, BlockingCollection<int> output)
{
int nLines = 0;
string line;
while ((line = input.Take()) != null)
{
Console.WriteLine(line);
++nLines;
}
output.Add(nLines);
}
static void FileReader(BlockingCollection<int> input, BlockingCollection<string> output)
{
StreamReader file = new StreamReader("input.txt"); // TODO: check exceptions
string line;
while ((line = file.ReadLine()) != null)
{
output.Add(line);
}
output.Add(null); // EOF
Console.WriteLine("line count: " + input.Take());
}
}
}

View file

@ -1,56 +1,54 @@
package main
import (
"fmt"
"bufio"
"io"
"os"
"bufio"
"fmt"
"io"
"os"
)
// main, one of two goroutines used, will function as the "reading unit"
func main() {
// get file open first
f, err := os.Open("input.txt")
if err != nil {
fmt.Println(err)
return
}
defer f.Close()
lr := bufio.NewReader(f)
// get file open first
f, err := os.Open("input.txt")
if err != nil {
fmt.Println(err)
return
}
defer f.Close()
lr := bufio.NewReader(f)
// that went ok, now create communication channels,
// and start second goroutine as the "printing unit"
lines := make(chan string)
count := make(chan int)
go printer(lines, count)
// that went ok, now create communication channels,
// and start second goroutine as the "printing unit"
lines := make(chan string)
count := make(chan int)
go printer(lines, count)
for {
line, prefix, err := lr.ReadLine()
switch {
case err == io.EOF:
case err != nil:
fmt.Println(err)
case prefix:
fmt.Println("unexpected long line")
default:
lines <- string(line)
continue
}
break
}
// this represents the request for the printer to send the count
close(lines)
// wait for the count from the printer, then print it, then exit
fmt.Println("Number of lines:", <-count)
for {
switch line, err := lr.ReadString('\n'); err {
case nil:
lines <- line
continue
case io.EOF:
default:
fmt.Println(err)
}
break
}
// this represents the request for the printer to send the count
close(lines)
// wait for the count from the printer, then print it, then exit
fmt.Println("Number of lines:", <-count)
}
func printer(in <-chan string, count chan<- int) {
c := 0
// loop as long as in channel stays open
for s := range in {
fmt.Println(s)
c++
}
// make count available on count channel, then return (terminate goroutine)
count <- c
c := 0
// loop as long as in channel stays open
for s := range in {
fmt.Print(s)
c++
}
// make count available on count channel, then return (terminate goroutine)
count <- c
}

View file

@ -0,0 +1,10 @@
input=: 1 :0
nlines=: 0
u;._2@fread 'input.txt'
smoutput nlines
)
output=: 3 :0
nlines=: nlines+1
smoutput y
)

View file

@ -0,0 +1 @@
output input

View file

@ -0,0 +1,59 @@
:- module synchronous_concurrency.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is cc_multi.
:- implementation.
:- import_module int, list, string, thread, thread.channel, thread.mvar.
:- type line_or_stop
---> line(string)
; stop.
main(!IO) :-
io.open_input("input.txt", Res, !IO),
(
Res = ok(Input),
channel.init(Channel, !IO),
mvar.init(MVar, !IO),
thread.spawn(writer(Channel, MVar, 0), !IO),
reader(Input, Channel, MVar, !IO)
;
Res = error(Err),
io.format("Error opening file: %s\n", [s(io.error_message(Err))], !IO)
).
:- pred reader(io.text_input_stream::in, channel(line_or_stop)::in, mvar(int)::in,
io::di, io::uo) is det.
reader(Input, Channel, MVar, !IO) :-
io.read_line_as_string(Input, Res, !IO),
(
Res = ok(Line),
channel.put(Channel, line(Line), !IO),
reader(Input, Channel, MVar, !IO)
;
Res = eof,
channel.put(Channel, stop, !IO),
mvar.take(MVar, Count, !IO),
io.format("%d lines printed.\n", [i(Count)], !IO)
;
Res = error(Err),
channel.put(Channel, stop, !IO),
io.format("Error reading file: %s\n", [s(io.error_message(Err))], !IO)
).
:- pred writer(channel(line_or_stop)::in, mvar(int)::in, int::in,
io::di, io::uo) is cc_multi.
writer(Channel, MVar, Count, !IO) :-
channel.take(Channel, LineOrStop, !IO),
(
LineOrStop = line(Line),
io.write_string(Line, !IO),
writer(Channel, MVar, Count + 1, !IO)
;
LineOrStop = stop,
mvar.put(MVar, Count, !IO)
).