Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Why You Should Avoid Processes
Index -> Programming, Turing -> Turing Tutorials
Goto page 1, 2, 3, 4, 5, 6, 7  Next
View previous topic Printable versionDownload TopicRate TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
Cervantes




PostPosted: Sat Feb 19, 2005 11:29 am   Post subject: Why You Should Avoid Processes

For the somewhat new programmer, using processes may seem almost manditory. You may want to do two things simultaneously and immediately think, "I can use a process for that!" But when you think that, you're making a big mistake.
In Turing, processes are terrible. They should be avoided at all costs (really, the only time they should be used is for playing music, but Turing 4.0.5 makes it so we don't even need them for that).
"Why are processes so terrible," you ask? Well, take a look at the example in the help file:
Turing:

process greetings (word : string)
    loop
        put word
    end loop
end greetings

fork greetings ("Hi")
fork greetings ("Ho")

Run it. After a second, stop it. You should see a very inconsistant pattern on the screen. This is because the processes execute at different (almost random, it seems) speeds. It's not as though greetings ("Hi") executes once, then greetings ("Ho") once, then once again for greetings ("Hi"), etc. No, Turing's processes don't work the way you want them to.
"But I don't care if they work at different rates!", you yell.
Aah, you should. Lets say we've got two objects, and we want to move them across the screen. object1 has a speed of 1, and object2 has a speed of 2. Both must travel the same distance. Using processes, object 2 will likely not reach its destination twice as fast as object1. Rather, it will reach its destination approximately twice as fast as object1. This may not seem like a big issue, but it is. You never know how your program is going to behave, because the processes run in a random fashion.

Actually I just discovered another bad thing about processes: you can't use "var" parameters. ie. you can't go
code:
process move (var foo : string)


We'll let Hacker Dan finish this for us:
Hacker Dan wrote:

Process can be good but you have to understand how they work and turing has limited conortl over them. Since turing has no way to set proity of a process all you know is that the code may run at some time. So baliky unless you got a dual CPU system a process will run lines of code in it at basicly random times durning the excution of your progame. If it dose not mater when they run then it could be good to use them but it gives you less conortl over things.



In conclusion, don't use processes. They are evil. If you choose to use them, fine, but you are only hurting your own program. You'll probably end up spending hours down the line reworking everything to eliminate the processes.


I'm no expert on this matter, but so many people have been trying to/using processes lately I felt something had to be done. Any elaboration on this matter, or more convincing/moral support, is welcome.

-Cervantes
Sponsor
Sponsor
Sponsor
sponsor
cycro1234




PostPosted: Sat Feb 19, 2005 12:21 pm   Post subject: (No subject)

Wow, thanks for that tutorial!

But If I shouldn't use processes to make 2 things run at the same time, I use instead? Like, what if I'm making a game and I want the person to shoot and move at the same time. How will I work that out? Or what If i want to animate 2 objects at the same time doing different actions unrelated to each other.
Martin




PostPosted: Sat Feb 19, 2005 1:04 pm   Post subject: (No subject)

No. Your main loop should look like this:

code:
loop
   if up arrow pressed then
      playery  += 1
   end if
   if left arrow pressed then
      playerx += 1
   end if
   if ...
      ...
   end if
   for i : 1 .. numBullets
      updatebulletposition(i)
   end for
   drawScene %player, bullets, etc.
end loop


The absolute only time that you should ever use a process is when you are doing sound.
cycro1234




PostPosted: Sat Feb 19, 2005 1:08 pm   Post subject: (No subject)

Ok. Thanks.
Cervantes




PostPosted: Sat Feb 19, 2005 1:31 pm   Post subject: (No subject)

Basically, you stick it all in the same loop. As to how to do it (well, it's really easy, but if you're stuck thinking in terms of processes, it might be a little difficult), the easiest way to show you how is with examples.

cycro1234 wrote:
Like, what if I'm making a game and I want the person to shoot and move at the same time.

There's an easy one. Shooting and moving is the same, in that both rely on input from the keyboard (or mouse).
Turing:

var x, y := 100

var keys : array char of boolean

proc fire
    %code
end fire
loop

    Input.KeyDown (keys)
    if keys (KEY_CTRL) then
        fire
    end if
    if keys (KEY_UP_ARROW) then
        y += 1
    end if
    if keys (KEY_DOWN_ARROW) then
        y -= 1
    end if
    if keys (KEY_RIGHT_ARROW) then
        x += 1
    end if
    if keys (KEY_LEFT_ARROW) then
        x -= 1
    end if

    cls
    drawfilloval (x, y, 5, 5, black)
    delay (10)

end loop

All you have to do is make your fire procedure. How you do that is related to your second question.
cycro1234 wrote:

Or what If i want to animate 2 objects at the same time doing different actions unrelated to each other.

There is always something that is related. Always. What is related is time. Just as my fingers move to type this, our solar system is hurtling around the Milky Way at 900 000km/h. We have two objects (my fingers, and the solar system) whose motions pretty well don't affect one another, but are nonetheless related through time. Every hour that my fingers move, the solar system travels 900 000km. Or, every hour that my fingers don't move, the solar system travels 900 000km. No matter what, the motions of the two objects are joined by time.
Because the motions are joined by time, we want to avoid using a process. Using a process would be like randomly accelerating time for one object, and slowing time for another. By using just one loop, however, we can keep time going at a constant pace.
Below you'll find three programs. The first is really all that I need to show how you do this without using processes. The second program is the same code, but much neater. The last uses many objects. Smile

Turing:

View.Set ("offscreenonly")
var ballx := 0.0
var bally := 50.0
var ballvx := 2
var ballvy := 0.6

var starx := 50.0
var stary := 150.0
var starvx := 2.5
var starvy := -0.3

loop
    ballx += ballvx
    bally += ballvy
    starx += starvx
    stary += starvy

    cls
    Draw.FillOval (round (ballx), round (bally), 15, 15, brightred)
    Draw.FillStar (round (starx - 15), round (stary - 15), round (starx + 15), round (stary + 15), brightblue)
    %the 15 is half the width and half the height.  Remember the star is drawn with x1, y1, x2, y2
    View.Update
    delay (15)
end loop


Here's the same thing, but neater. Types are always nice for keeping things organized.
Turing:

View.Set ("offscreenonly")
type obj :
    record
        x : real
        y : real
        vx : real
        vy : real
    end record

var ball : obj
ball.x := 0
ball.y := 50
ball.vx := 2
ball.vy := 0.6

var star : obj
star.x := 50
star.y := 150
star.vx := 2.5
star.vy := -0.3

loop
    ball.x += ball.vx
    ball.y += ball.vy
    star.x += star.vx
    star.y += star.vy

    cls
    Draw.FillOval (round (ball.x), round (ball.y), 15, 15, brightred)
    Draw.FillStar (round (star.x - 15), round (star.y - 15), round (star.x + 15), round (star.y + 15), brightblue)
            %the 15 is half the width and half the height.  Remember the star is drawn with x1, y1, x2, y2
    View.Update
    delay (15)
end loop


The next code takes the motion section (the ball.x += ball.vx etc. part) and sticks it into a procedure. Then it uses that procedure many times, for there are many more objects in this one. Smile

Turing:

View.Set ("offscreenonly")
type obj :
    record
        x : real
        y : real
        vx : real
        vy : real
    end record

var ball : array 1 .. 30 of obj
for i : 1 .. upper (ball)
    ball (i).x := Rand.Int (0, maxx)
    ball (i).y := Rand.Int (0, maxy)
    ball (i).vx := Rand.Int (-3, 3)
    ball (i).vy := Rand.Int (-3, 3)
end for

procedure moveObj (var obj : obj)
    obj.x += obj.vx
    obj.y += obj.vy
end moveObj

loop
   
    %Move all the balls
    for i : 1 .. upper (ball)
        moveObj (ball (i))
    end for


    cls
   
    %Draw all the balls
    for i : 1 .. upper (ball)
        Draw.FillOval (round (ball (i).x), round (ball (i).y), 15, 15, brightred)
    end for
    View.Update
    delay (15)
end loop


Hopefully that wasn't hard to get through.

To recap: don't use processes, because doing so means you're screwing with time. Use a single main loop. The concept is no different than using processes. You just have to keep your main loop structured nicely. (ie. keep all your drawing at the end, all your input at the beginning, and all your variable manipulation in the middle).

-Cervantes
Tony




PostPosted: Sat Feb 19, 2005 1:31 pm   Post subject: (No subject)

I'd like to add that if both processes use the same global variable, the results will be disastrous.

You essensially throw your code flow into a blender, mix it up and say. "Here I have a bunch of lines of code. They are in no particular order. If the computer happens to pick the right order - the results will be as expected. Otherwise I have no idea what might happen"
cycro1234




PostPosted: Sat Feb 19, 2005 1:45 pm   Post subject: (No subject)

Ok, thanks a lot for that guys! I get it a lot more now. Very Happy

But if processes are so useless, why were they added in Turing? Only to make music run?
Cervantes




PostPosted: Sat Feb 19, 2005 3:33 pm   Post subject: (No subject)

Processes (threads?) are not a feature of Turing alone. Many other languages have them, though I believe their processes actually work orderly, not randomly. I can only assume Holtsoft tried to give Turing what those other languages have. Boy did they fail...
Sponsor
Sponsor
Sponsor
sponsor
Flikerator




PostPosted: Sat Feb 19, 2005 6:00 pm   Post subject: (No subject)

For my final project (Pong) I used like 6 forks. Ai, paddle, paddle2 (2 player), music, lives, and ball. I wouldn't do anything like that cause now I am not so nubish anymore.

I pulled a 90 out of my first year with that sort of programming lolz.


Quote:
the only time they should be used is for playing music, but Turing 4.0.5 makes it so we don't even need them for that


What do you mean, how do we play music without using a process? This will help greatly in Zombie Mass'Acres Very Happy
rizzix




PostPosted: Sun Feb 20, 2005 12:40 am   Post subject: (No subject)

hmm i dont get it.. what do u guys mean by random? the lines of code executed with the process code-block is random? (quite impossible) if so, never use processes. if not.. there is nothing wrong with the processes. they are just fine, just that you guys are not used to concurrent programming.
md




PostPosted: Sun Feb 20, 2005 1:17 am   Post subject: (No subject)

Cervantes wrote:
Processes (threads?) are not a feature of Turing alone. Many other languages have them, though I believe their processes actually work orderly, not randomly. I can only assume Holtsoft tried to give Turing what those other languages have. Boy did they fail...


Threads (as processes are really known) are actually a feature of the OS (windows), or very low level code (linux can use kernel threads and user threads [i think], basically their only different in what does the schedualing). However your wrong in your assumption that they are run in an orderly fasion.

Say we have two threads, A and B. Thread A will be run for a given time (a very small ammount of time...), then thread B will be given a chance.

The problem is when unshedualed things happen, say a keystroke. The OS must then switch from the thread to the keyboard handling process which will then run until it is done or something else interupts it. Once the keyboard process is done the OS returns execution back to the next ready process (not nessarilly ours). The next time it gets arround to running our process it will probably run the next thread in the queue (which, again, will probably not be the one that was interupted).

Thus something as trivial as an interupt can cause any thread to lose some of it's execution time. And since interupts are generated by almost all hardware and at a fairly high rate, execution times are not perfectly balanced.

Of course modern threads can be prioritized, or blocked (set not to run), so in practice threads are actually are very usefull tool. Although I wouldn't recomend creating a lot of threads, as each thread adds overhead, and creating one for such a simple task as an animation is frivilous.
cycro1234




PostPosted: Tue Feb 22, 2005 4:55 pm   Post subject: (No subject)

I have this code to shoot and move, but it's not working:

code:

View.Set ("offscreenonly")

var chars : array char of boolean
var x, y : int := 100
forward proc movement

proc shoot (var y : int)
    loop
        y := y + 1
        drawoval (x+35,y-1,10,10,0)
        drawoval (x+35,y,10,10,7)
        drawoval (x-35,y-1,10,10,0)
        drawoval (x-35,y,10,10,7)
        View.Update
        exit when y + 20 > maxy
        movement
    end loop
end shoot

body proc movement
    loop
        Input.KeyDown (chars)
        if chars (KEY_UP_ARROW) and y + 64 < maxy then
            y := y + 1
        elsif chars (KEY_DOWN_ARROW) and y > 0 then
            y := y - 1
        elsif chars (KEY_LEFT_ARROW) and x > 0 then
            x := x - 1
        elsif chars (KEY_RIGHT_ARROW) and x + 64 < maxx then
            x := x + 1
        elsif chars (KEY_CTRL) then
            shoot (y)
        end if
        cls
        drawfilloval (x,y,20,20,7)
        View.Update
    end loop
end movement

loop
    movement
end loop


Hold ctrl to shoot and move with arrow keys.

I thought that if I called movement in the procedure shoot then I could shoot and move at the same time. It doesn't work! The y value that I need for the bullet interferes wit the y value of the position of the circle. After shooting the bullets, the y value of them is stored and is used to draw the cirle in a place i do not need. Any ideas how to fix?
jamonathin




PostPosted: Tue Feb 22, 2005 8:13 pm   Post subject: (No subject)

You have to give the bullet's their own variables. 'x' and 'y' are already used by the "shooter" and so by adding to the y-value, you're changing where the shooter is. This is what i came up with. .
code:

View.Set ("offscreenonly")

var chars : array char of boolean
var x, y, bullety, bulletx : int := 100
var shot : int := 0
forward proc movement

proc shoot
    loop
        shot := 1
        bullety += 1
        exit when bullety + 20 > maxy
        movement
    end loop
    shot := 0
end shoot

body proc movement
    Input.KeyDown (chars)
    if chars (KEY_UP_ARROW) and y + 64 < maxy then
        y := y + 1
    elsif chars (KEY_DOWN_ARROW) and y > 0 then
        y := y - 1
    elsif chars (KEY_LEFT_ARROW) and x > 0 then
        x := x - 1
    elsif chars (KEY_RIGHT_ARROW) and x + 64 < maxx then
        x := x + 1
    end if
    if chars (KEY_CTRL) and shot = 0 then
        bullety := y
        bulletx := x
        shoot
    end if
    cls
    if shot = 1 then
        drawoval (bulletx + 35, bullety - 1, 10, 10, 0)
        drawoval (bulletx + 35, bullety, 10, 10, 7)
        drawoval (bulletx - 35, bullety - 1, 10, 10, 0)
        drawoval (bulletx - 35, bullety, 10, 10, 7)
    end if
    drawfilloval (x, y, 20, 20, 7)
    View.Update
end movement

loop
    movement
end loop

The shooter moves a little slower while the bullets are being fired however. If you want, you can have a variable represent the displacement of the shoot (y + 1 to y + dif), and when the ball is being fired, dif will equal 2, but outside the loop, dif will equal 1, your choice. Confused
cycro1234




PostPosted: Tue Feb 22, 2005 10:06 pm   Post subject: (No subject)

K got it. Thx.
HyperFlexed




PostPosted: Wed Feb 23, 2005 10:04 pm   Post subject: (No subject)

Never looked into it but I believe Turing has a way to set the priorities of processes. I must agree though, many people failed my compsci class because they used them innapropriately.

One guy made this game where red and black blocks float across the screen and you gotta hit the red and avoid the black. Not only did he use processes, he made one process for each block rather than passsing in the values (I suppose it'd be redundant eather way).

The biggest thing to understand is a computer goes so fast, you don't have to worry to much about the order of how things are done. And if you are using View.Update and getting everything at once, your user won't get screwed, and your program will be alot faster for it.


that reminds me, I should post my final project. I made tetris, hehe.
Display posts from previous:   
   Index -> Programming, Turing -> Turing Tutorials
View previous topic Tell A FriendPrintable versionDownload TopicRate TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 7  [ 99 Posts ]
Goto page 1, 2, 3, 4, 5, 6, 7  Next
Jump to:   


Style:  
Search: