[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[pygame] Help



Ok, so I got multicore working and didn't kil my pc. However, the
threads aren't really doing what I want them to do. anyone know why The
main python process amx's out and the rest are left at ~1% cpu?

(I have many cores, so one core isn't the issue)
import pygame
import random

import multiprocessing
import time
import math

width = 1000
height = 800



class Consumer(multiprocessing.Process):
    
    def __init__(self, task_queue, result_queue):
        multiprocessing.Process.__init__(self)
        self.task_queue = task_queue
        self.result_queue = result_queue

    def run(self):
        proc_name = self.name
        while True:
            next_task = self.task_queue.get()
            if next_task is None:
                # Poison pill means we should exit
                print '%s: Exiting' % proc_name
                break
            #print '%s: %s' % (proc_name, next_task)
            answer = next_task[0](*next_task[1])
            self.result_queue.put(answer)
        return


class Task(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b
    def __call__(self):
        time.sleep(0.1) # pretend to take some time to do our work
        return '%s * %s = %s' % (self.a, self.b, self.a * self.b)
    def __str__(self):
        return '%s * %s' % (self.a, self.b)


    
def end():
    for i in xrange(num_consumers):
        tasks.put(None)


def attract(itemlist, gravitar):
    for i in itemlist:
        if i.id != gravitar.id:
            xdiff = gravitar.x - i.x  
            ydiff = gravitar.y - i.y
            dist = math.sqrt((xdiff**2)+(ydiff**2))
            force = 2*(i.mass*gravitar.mass)/(dist**2)
            acceleration = force / gravitar.mass
            xc = xdiff/dist
            yc = ydiff/dist
            gravitar.dx -= acceleration * xc
            gravitar.dy -= acceleration * yc
    gravitar.x += gravitar.dx
    gravitar.y += gravitar.dy
    if gravitar.x > width or gravitar.x < 0:
        gravitar.dx *= -1
    if gravitar.y > height or gravitar.y < 0:
        gravitar.dy *= -1
    gravitar.dx *= .999
    gravitar.dy *= .999
    return gravitar
    
class Gravitar(object):
    def __init__(self, id):
        self.id = id
        self.x = random.random()*width
        self.y = random.random()*height
        self.dx = 0
        self.dy = 0
        self.mass = random.randint(1,6)

def genlist():
    n = []
    for i in xrange( 2000):
        n.append(Gravitar(i))
    return n

if __name__ == '__main__':
    
    pygame.init()
    screen = pygame.display.set_mode((width, height))
    
    
    # Establish communication queues
    
    
    tasks = multiprocessing.Queue()
    results = multiprocessing.Queue()
    
    # Start consumers
    num_consumers = multiprocessing.cpu_count() * 8
    print 'Creating %d consumers' % num_consumers
    consumers = [ Consumer(tasks, results)
                  for i in xrange(num_consumers) ]
    for w in consumers:
        w.start()
    
    # Enqueue jobs
    
    
    # Add a poison pill for each consumer
    result = genlist()

    # Start printing results
    x = 0
    while True:
        ## blit all here
        
        x += 1    
        
        screen.fill((0,0,0))
        for item in result:
            pygame.draw.circle(screen, (255,255,255), ( int(item.x), int(item.y)), int(item.mass))
        x = -1
        for gtar in result:
            x += 1
            tasks.put([attract,[result, gtar]])
        was = len(result)
        result = []
        print "Calculating frame"
        while True:
            pygame.event.get()
            pygame.display.update()
            result.append(results.get())
            print len(result), "/", was
            if len(result) == was:
                break