如何衡量这个餐饮哲学家程序(python)的执行时间?

时间:2013-11-26 18:12:24

标签: python

from __future__ import print_function
from threading import Semaphore, Lock, Thread
from time import sleep
from random import random
import argparse
from timeit import Timer

(THINKING, EATING) = (0, 1) #philosopher states

def left_fork(id):
    return id

def right_fork(id):
    return (id+1) % NUM_PHILOSOPHER

def right(id):
    return (id+1) % NUM_PHILOSOPHER

def left(id):
    return (id+NUM_PHILOSOPHER-1) % NUM_PHILOSOPHER

def get_fork(id):
    global mutex
    global tstate
    global sem

    mutex.acquire()
    tstate[id] = 'hungry'
    test(id)
    mutex.release()
    sem[id].acquire()

def put_fork(id):
    global mutex
    global tstate
    global sem

    mutex.acquire()
    tstate[id] = 'thinking'
    test(right(id))
    test(left(id))
    mutex.release()

def test(id):
    global tstate
    if tstate[id] == 'hungry' and tstate[left(id)] != 'eating' and tstate[right(id)] != 'eating':   
        tstate[id] = 'eating'
        sem[id].release()

def philosophize_footman(id,meal):
    global forks
    global footman
    state = THINKING
    for i in range(meal):
        sleep(random())
        if(state == THINKING):
            msg = "Philosopher " + str(id) + " is thinking."
            #print(msg)
            footman.acquire()
            forks[right_fork(id)].acquire()
            forks[left_fork(id)].acquire()
            state = EATING
        else:
            msg = "Philosopher " + str(id) + " is eating."
            #print(msg)
            forks[right_fork(id)].release()
            forks[left_fork(id)].release()
            state = THINKING
            footman.release()
    print("Finish philosophize_footman")

def philosophize_lefthand(id,meal):
    global forks
    state = THINKING
    for i in range(meal):
        sleep(random())
        if(state == THINKING):
            #define the left hand user.
            if(id == 3):
                forks[left_fork(id)].acquire()
                forks[right_fork(id)].acquire()
                state = EATING
            else:
                forks[right_fork(id)].acquire()
                forks[left_fork(id)].acquire()
                state = EATING
        else:
            if(id == 3):
                forks[left_fork(id)].release()
                forks[right_fork(id)].release()
                state == THINKING   
            else:
                forks[right_fork(id)].release()
                forks[left_fork(id)].release()
                state == THINKING
    print("Finish philosophize_lefthand")

def philosophize_Tanenbaum(id,meal):
    for i in range(meal):
        get_fork(id)
        sleep(random())
        put_fork(id)
    print("Finish philosophize_Tanenbaum")

def run_c(numP,numM):
    for m in range(numP):
        phil1 = Thread(target = philosophize_Tanenbaum,args = (m,numM))
        phil1.start()

def run_a():
    global NUM_PHILOSOPHER
    global MEAL
    for i in range(NUM_PHILOSOPHER):
        phil = Thread(target = philosophize_footman, args = (i,MEAL))
        phil.start()

def run_b(numP,numM):
    for n in range(numP):
        phil2 = Thread(target = philosophize_lefthand, args = (n,numM))
        phil2.start()


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description = 'Philosopher dining')
    parser.add_argument('--nphi','-n',
                        type = int,
                        default = 5,
                        help = 'add num_phi',
                        metavar = 'number of philosophers')
    parser.add_argument('--meal','-m',
                        type = int,
                        default = 100,
                        help = 'number of meals',
                        metavar = 'meal')
    args = parser.parse_args()
    NUM_PHILOSOPHER = args.nphi #define number fo philosophers
    MEAL = args.meal    #define number of meals
    forks = [Semaphore(1) for i in range(NUM_PHILOSOPHER)]  #defines forks
    sem = [Semaphore(0) for i in range(NUM_PHILOSOPHER)]    #semaphores
    footman = Semaphore(4) #limit the number of philosophers
    mutex = Semaphore(1)    #mutex
    tstate = ['thinking'] * NUM_PHILOSOPHER #T-states

    run_a()
#   run_b(args.nphi,args.meal)
#   run_c(args.nphi,args.meal)
    timer = Timer(run_a)
    print("Time:{:0.3f}s".format(timer. timeit(100)/100))

是python的餐饮问题解决方案。代码如上所列。我想测量函数run_a()的运行时间。但是当使用计时器时,我发现它不能正常工作。它立即打印时间结果(例如0.001s,但代码仍在运行。)所以请帮助我!非常感谢你。

1 个答案:

答案 0 :(得分:3)

你需要等待线程完成;在每个帖子上调用Thread.join()

def run_a():
    global NUM_PHILOSOPHER
    global MEAL
    threads = []
    for i in range(NUM_PHILOSOPHER):
        phil = Thread(target = philosophize_footman, args = (i,MEAL))
        phil.start()
        threads.append(phil)

    for t in threads:
        t.join()

Thread.join()方法阻塞直到线程完成,或者您可以指定超时。