acmjudger
acmjudger copied to clipboard
ACM在线测评系统评测程序设计与实现
ACMå¨çº¿æµè¯ç³»ç»è¯æµç¨åºè®¾è®¡ä¸å®ç°
åæ¤æç®ç
- 让å¤è¡äººäºè§£ACMï¼éè§ACM
- 让ACMeräºè§£è¯æµç¨åºè¯æµåç以便æ´å¥½å¾åé¢
- 让pythoneräºè§£å¦ä½ä½¿ç¨æ´å¥½ç使ç¨python
å¨è®²è§£ä¹åï¼å ç»å¤è¡äººè¡¥å ä¸äºå ³äºACMçç¥è¯ã
ä»ä¹æ¯ACMï¼
æ们平常æçACMæ¯ACM/ICPC
ï¼å½é
大å¦çç¨åºè®¾è®¡ç«èµï¼ï¼è¿æ¯ç±ACMï¼Association for Computing Machineryï¼ç¾å½è®¡ç®æºåä¼ï¼ç»ç»ç年度æ§ç«èµï¼å§äº1970å¹´ï¼æ¯å
¨ç大å¦ç计ç®æºç¨åºè½åç«èµæ´»å¨ä¸ææå½±åçä¸é¡¹èµäºã被èªä¸ºè®¡ç®æºç奥æå¹å
ã
äºè§£æ´å¤å ³äºACMçä¿¡æ¯å¯ä»¥åèï¼
- ç¾åº¦ç¾ç§ï¼http://baike.baidu.com/view/201684.htm
- ç»´åºç¾ç§ï¼http://zh.wikipedia.org/wiki/ACMå½é 大å¦çç¨åºè®¾è®¡ç«èµ
- ACMå½é 大å¦çç¨åºè®¾è®¡ç«èµæå:http://xinxi.100xuexi.com/view/trend/20120328/47133.html
ä»ä¹æ¯ACMæµè¯ç³»ç»ï¼
为äºè®©åå¦ä»¬æ¥æä¸ä¸ªç»ä¹ åæ¯èµçç¯å¢ï¼éè¦ä¸å¥ç³»ç»æ¥æä¾æå¡ã
ç³»ç»è¦æä¾å¦ä¸åè½ï¼
- ç¨æ·ç®¡ç
- é¢ç®ç®¡ç
- æ¯èµç®¡ç
- è¯æµç¨åº
å ¸åçACMè¯æµç³»ç»æ两ç§
- ä¸ç§æ¯C/S模å¼ï¼å ¸å代表æ¯PC^2ã主è¦ç¨å¨çèµï¼åºé¢èµï¼å½é èµç大åæ¯èµä¸ãå®ç½ï¼http://www.ecs.csus.edu/pc2/
- å¦ä¸ç§æ¯B/S模å¼ï¼å½å
å¤æå å个类似ç½ç«ï¼ä¸»è¦ç¨äºå¹³å¸¸ç»ä¹ åæå¦çãå½å
æ¯è¾æµè¡çOJæï¼
- æå·çµåç§æ大å¦ï¼http://acm.hdu.edu.cn/
- å京大å¦ï¼http://poj.org/
- æµæ±å¤§å¦ï¼http://acm.zju.edu.cn/onlinejudge/
- å±±ä¸ç工大å¦ï¼http://acm.sdut.edu.cn/sdutoj/index.php
è¯æµç¨åºæ¯åä»ä¹çï¼
è¯æµç¨åºå°±æ¯å¯¹ç¨æ·æ交ç代ç è¿è¡ç¼è¯ï¼ç¶åæ§è¡ï¼å°æ§è¡ç»æåOJåå°æ£ç¡®çæµè¯æ°æ®è¿è¡æ¯è¾ï¼å¦æçæ¡ååå°æ°æ®å®å ¨ç¸åå°±æ¯AC(Accept)ï¼ä¹å°±æ¯ä½ çç¨åºæ¯æ£ç¡®çãå¦åè¿åé误信æ¯ï¼ç¨åä¼è¯¦ç»è®²è§£ã
ACMå¨çº¿æµè¯ç³»ç»æ´ä½æ¶æ
为äºåå°ä½è¦åï¼æ们以æ°æ®åºä¸ºä¸å¿ï¼åå°é¡µé¢ä»æ°æ®åºè·åé¢ç®ãæ¯èµå表å¨æµè§å¨ä¸æ¾ç¤ºï¼ç¨æ·éè¿æµè§å¨æ交ç代ç ç´æ¥ä¿åå°æ°æ®åºã
è¯æµç¨åºè´è´£ä»æ°æ®åºä¸ååºç¨æ·ååæ交ç代ç ï¼ä¿åå°æ件ï¼ç¶åç¼è¯ï¼æ§è¡ï¼è¯å¤ï¼æåå°è¯å¤ç»æååæ°æ®åºã
è¯æµç¨åºæ¶æ
è¯æµç¨åºè¦ä¸ææ«ææ°æ®åºï¼ä¸æ¦åºç°æ²¡æè¯å¤çé¢ç®è¦ç«å³è¿è¡è¯å¤ã为äºåå°é¢ç¹è¯»åæ°æ®åºé æçå
ååCPU以å硬çå¼éï¼å¯ä»¥æ¯é0.5ç§æ«æä¸æ¬¡ã为äºæé«è¯æµé度ï¼å¯ä»¥å¼å¯å 个è¿ç¨æ线ç¨å
±åè¯æµãç±äºå¤çº¿ç¨/è¿ç¨ä¼ç«äºèµæºï¼å¯¹äºæ«æåºæ¥çä¸ä¸ªé¢ç®ï¼å¦æå¤ä¸ªè¯æµè¿ç¨åæ¶å»è¯æµï¼å¯è½ä¼é ææ»éï¼ä¸ºäºé²æ¢è¿ç§ç°è±¡ï¼å¯ä»¥ä½¿ç¨äºç产è
-æ¶è´¹è
模å¼ï¼ä¹å°±æ¯å»ºç«ä¸ä¸ªå¾
è¯æµé¢ç®çä»»å¡éåï¼è¿ä¸ªéåçç产è
ä½ç¨å°±æ¯æ«ææ°æ®åºï¼å°æ°æ®åºä¸æ²¡æè¯æµçé¢ç®å表å¢å å°ä»»å¡éåéé¢ãæ¶è´¹è
ä½ç¨å°±æ¯ä»éåä¸ååºè¦è¯æµçæ°æ®è¿è¡è¯æµã
为ä»ä¹ä»»å¡éåè½é²æ¢åºç°èµæºç«äºåæ»éç°è±¡ï¼
pythonéé¢æ个模åå«Queue
ï¼æ们å¯ä»¥ä½¿ç¨è¿ä¸ªæ¨¡å建ç«ä¸ç§ç±»åçéåï¼
- FIFOï¼å è¿å åºéå
- LIFOï¼åè¿å åºéå
- ä¼å éå
è¿éæ们ç¨å°çæ¯å è¿å åºéåï¼ä¹å°±æ¯å 被添å å°éåç代ç å 被è¯æµï¼ä¿ææ¯èµçå ¬å¹³æ§ã
éåå¯ä»¥è®¾ç½®å¤§å°ï¼é»è®¤æ¯æ é大ã
ç产è åç°æ°æ®åºä¸åå¨æ²¡æè¯æµçé¢ç®ä¹åï¼ä½¿ç¨put()æ¹æ³å°ä»»å¡æ·»å å°éåä¸ãè¿æ¶åå¦æéå设置大å°å¹¶ä¸å·²ç»æ»¡äºçè¯ï¼å°±ä¸è½åå¾éé¢æ¾äºï¼è¿æ¶åç产è å°±è¿å ¥äºçå¾ ç¶æï¼ç´å°å¯ä»¥ç»§ç»å¾éé¢æ¾ä»»å¡ä¸ºæ¢ãå¨çå¾ ç¶æçä¹åç产è 线ç¨å·²ç»è¢«é»å¡äºï¼ä¹å°±æ¯è¯´ä¸åå»æ«ææ°æ®åºï¼å æ¤éå½è®¾ç½®éåç大å°å¯ä»¥åå°å¯¹æ°æ®åºç读å次æ°ã
æ¶è´¹è
éè¦ä»ä»»å¡éåè·åä»»å¡ï¼ä½¿ç¨get()
æ¹æ³ï¼ä¸æ¦æ个线ç¨ä»éåget
å¾å°æ个任å¡ä¹åï¼å
¶ä»çº¿ç¨å°±ä¸è½å次å¾å°è¿ä¸ªä»»å¡ï¼è¿æ ·å¯ä»¥é²æ¢å¤ä¸ªè¯æµçº¿ç¨åæ¶è¯æµåä¸ä¸ªç¨åºèé ææ»éãå¦æä»»å¡éå为空çè¯ï¼get()æ¹æ³ä¸è½è·å¾ä»»å¡ï¼è¿æ¶åè¯çº¿ç¨åºå°±ä¼é»å¡ï¼çå¾
ä»»å¡çå°æ¥ãå¨è¢«é»å¡çæ¶åè¯æµç¨åºå¯ä»¥è¢«çååæ¢è¿è¡äºï¼å¯ä»¥ææ¾åå°ç³»ç»èµæºæ¶èã
éåè¿æ两个æ¹æ³ï¼
ä¸ä¸ªæ¯task_done()
ï¼è¿ä¸ªæ¹æ³æ¯ç¨æ¥æ è®°éåä¸çæ个任å¡å·²ç»å¤çå®æ¯ã
å¦ä¸ä¸ªæ¯join()
æ¹æ³ï¼joinæ¹æ³ä¼é»å¡ç¨åºç´å°ææç项ç®è¢«å é¤åå¤ç为æ¢ï¼ä¹å°±æ¯è°ç¨task_done()
æ¹æ³ã
è¿ä¸¤ä¸ªæ¹æ³æä»ä¹ä½ç¨å¢ï¼å 为è¯æµä¹éè¦æ¶é´ï¼ä¸ä¸ªä»»å¡ä»éåä¸ååºæ¥äºï¼å¹¶ä¸æå³çè¿ä¸ªä»»å¡è¢«å¤çå®äºãå¦æ没æå¤çå®ï¼ä»£ç çç¶æè¿æ¯æªè¯å¤ï¼é£ä¹ç产è ä¼å次å°è¿ä¸ªä»£ç ä»æ°æ®åºååºå å°ä»»å¡éåéé¢ï¼è¿å°é æ代ç éå¤è¯æµï¼æµªè´¹ç³»ç»èµæºï¼å½±åè¯æµé度ãè¿æ¶åæ们éè¦åçç¨è¿ä¸¤ä¸ªæ¹æ³ï¼ä¿è¯æ¯ä¸ªä»£ç é½è¢«è¯æµå¹¶ä¸ååæ°æ®åºä¹åæå¼å§ä¸ä¸è½®çæ«æãåé¢æ代ç 示ä¾ã
æ们使ç¨å¦ä¸ä»£ç å建ä¸ä¸ªFIFOéåï¼
#åå§åéå
q = Queue(config.queue_size)
å¦ä½ææå¾ä»æ°æ®åºè·åæ°æ®ï¼
è¿éæ们以mysql为ä¾è¿è¡è¯´æãpythonææ°æ®åºç¸å ³ç模åï¼ä½¿ç¨èµ·æ¥å¾æ¹ä¾¿ãè¿éæ们éè¦èèå¼å¸¸å¤çã
æå¯è½åºç°çé®é¢æ¯æ°æ®åºéå¯äºæè å¶å°æå¼äºä¸è½æ£å¸¸è¿æ¥ï¼è¿æ¶åå°±éè¦ä¸æå°è¯éæ°è¿æ¥ç´å°è¿æ¥æåãç¶åå¤æåæ°ï¼å¦ææ¯å符串就说ææ¯sqlè¯å¥ï¼ç´æ¥æ§è¡ï¼å¦ææ¯å表åä¾æ¬¡æ§è¡ææçè¯å¥ï¼å¦ææ§è¡æé´åºç°é误ï¼åå ³éè¿æ¥ï¼è¿åé误信æ¯ãå¦åè¿åsqlè¯å¥æ§è¡ç»æã
ä¸é¢è¿ä¸ªå½æ°ä¸é¨æ¥å¤çæ°æ®åºç¸å ³æä½
def run_sql(sql):
'''æ§è¡sqlè¯å¥,并è¿åç»æ'''
con = None
while True:
try:
con = MySQLdb.connect(config.db_host,config.db_user,config.db_password,
config.db_name,charset=config.db_charset)
break
except:
logging.error('Cannot connect to database,trying again')
time.sleep(1)
cur = con.cursor()
try:
if type(sql) == types.StringType:
cur.execute(sql)
elif type(sql) == types.ListType:
for i in sql:
cur.execute(i)
except MySQLdb.OperationalError,e:
logging.error(e)
cur.close()
con.close()
return False
con.commit()
data = cur.fetchall()
cur.close()
con.close()
return data
éè¦æ³¨æçæ¯è¿éæ们æ¯æ¬¡æ§è¡sqlè¯å¥é½è¦éæ°è¿æ¥æ°æ®åºï¼è½å¦ä¸æ¬¡è¿æ¥ï¼å¤æ¬¡æä½æ°æ®åºï¼çæ¡æ¯è¯å®çãä½æ¯ï¼è¿éæ们éè¦èèçé®é¢æ¯å¦ä½å°æ°æ®åºçè¿æ¥å ±äº«ï¼å¯ä»¥è®¾ç½®ä¸ä¸ªå ¨å±åéãä½æ¯å¦ææ°æ®åºçè¿æ¥çªç¶æå¼äºï¼å¨å¤çº¿ç¨ç¨åºéé¢ï¼é®é¢å°±æ¯è¾éº»ç¦äºï¼ä½ éè¦å¨æ¯ä¸ªç¨åºéé¢å»å¤ææ¯å¦è¿æ¥æåï¼å¤±è´¥çè¯è¿è¦éæ°è¿æ¥ï¼å¤çº¿ç¨æ åµä¸å¦ä½æ§å¶éæ°è¿æ¥ï¼è¿äºé®é¢å¦æå¨æ¯ä¸ªsqlè¯å¥æ§è¡çæ¶åé½å»æ£æ¥çè¯å¤ªéº»ç¦äºã
æä¸ç§æ¹æ³å¯ä»¥å®ç°ä¸æ¬¡è¿æ¥ï¼å¤æ¬¡æä½æ°æ®åºï¼è¿è½æ¹ä¾¿çè¿è¡æ°æ®åºéè¿ï¼é£å°±æ¯ä½¿ç¨yieldçæå¨ï¼è¿æ¥æåä¹åï¼éè¿yieldå°sqlè¯å¥ä¼ éè¿å»ï¼æ§è¡ç»æéè¿yieldåé¦åæ¥ãè¿æ ·å¬èµ·æ¥å¾å¥½ï¼ä½æ¯æ个é®é¢å®¹æ被忽ç¥ï¼é£å°±æ¯yieldå¨ä¸æ¯æå¤çº¿ç¨ï¼å¤ä¸ªçº¿ç¨åæ¶åyieldåéæ°æ®ï¼yieldæ¥æ¶è°ï¼yieldè¿åä¸ä¸ªæ°æ®ï¼è°å»æ¥æ¶ï¼è¿æ ·yieldå°±ä¼æ¥éï¼ç¶ååæ¢æ§è¡ãå½ç¶å¯ä»¥ä½¿ç¨ç¹æ®æ¹æ³å¯¹yieldè¿è¡å éï¼ä¿è¯æ¯æ¬¡é½åªæä¸ä¸ªçº¿ç¨åéæ°æ®ã
éè¿æµè¯åç°ï¼ä½¿ç¨yield并ä¸è½æé«è¯æµæçï¼èæ¯æ¬¡è¿æ¥æ°æ®åºä¹å¹¶ä¸æ ¢ï¼æ¯ç«ç°å¨æå¡å¨æ§è½é½å¾é«ãæ以使ç¨ä¸é¢çæ¯æ¬¡è¿æ¥æ°æ®åºçæ¹æ³è¿æ¯æ¯è¾å¥½çã
è¿æä¸ä¸ªé®é¢ï¼å½å¤çº¿ç¨åæ¶å¯¹æ°æ®åºè¿è¡æä½çæ¶åï¼ä¹å®¹æåºç°ä¸äºè«åå ¶å¦çé误ï¼æ好æ¯å¯¹æ°æ®åºæä½å éï¼
#å建æ°æ®åºéï¼ä¿è¯ä¸ä¸ªæ¶é´åªè½ä¸ä¸ªç¨åºé½åæ°æ®åº
dblock = threading.Lock()
# 读åæ°æ®åºä¹åå é
dblock.acquire()
# æ§è¡æ°æ®åºæä½
runsql()
# æ§è¡å®æ¯è§£é
dblock.release()
ç产è å¦ä½å»å®ç°ï¼
为äºéèæå¡å¨ä¿¡æ¯ï¼ä¿è¯æå¡å¨å®å ¨ï¼ææçSQLè¯å¥é½ç¨äºä¸ª#代æ¿ã
ç产è å°±æ¯ä¸ä¸ªwhileæ»å¾ªç¯ï¼ä¸ææ«ææ°æ®åºï¼æ«æå°ä¹åå°±åä»»å¡éåæ·»å ä»»å¡ã
def put_task_into_queue():
'''循ç¯æ«ææ°æ®åº,å°ä»»å¡æ·»å å°éå'''
while True:
q.join() #é»å¡å®ç¨åº,ç´å°éåéé¢çä»»å¡å
¨é¨å®æ
sql = "#####"
data = run_sql(sql)
for i in data:
solution_id,problem_id,user_id,contest_id,pro_lang = i
task = {
"solution_id":solution_id,
"problem_id":problem_id,
"contest_id":contest_id,
"user_id":user_id,
"pro_lang":pro_lang,
}
q.put(task)
time.sleep(0.5) #æ¯æ¬¡æ«é¢å®åçå¾
0.5ç§ï¼åå°CPUå æç
æ¶è´¹è å¦ä½å®ç°ï¼
åºæ¬æ¯æç §ä¸é¢è¯´çæ¥çï¼å è·åä»»å¡ï¼ç¶åå¤çä»»å¡ï¼æåæ è®°ä»»å¡å¤çå®æã
def worker():
'''å·¥ä½çº¿ç¨ï¼å¾ªç¯æ«æéåï¼è·å¾è¯å¤ä»»å¡å¹¶æ§è¡'''
while True:
#è·åä»»å¡ï¼å¦æéå为空åé»å¡
task = q.get()
#è·åé¢ç®ä¿¡æ¯
solution_id = task['solution_id']
problem_id = task['problem_id']
language = task['pro_lang']
user_id = task['user_id']
# è¯æµ
result=run(problem_id,solution_id,language,data_count,user_id)
#å°ç»æåå
¥æ°æ®åº
dblock.acquire()
update_result(result)
dblock.release()
#æ è®°ä¸ä¸ªä»»å¡å®æ
q.task_done()
å¦ä½å¯å¨å¤ä¸ªè¯æµçº¿ç¨ï¼
def start_work_thread():
'''å¼å¯å·¥ä½çº¿ç¨'''
for i in range(config.count_thread):
t = threading.Thread(target=worker)
t.deamon = True
t.start()
è¿éè¦æ³¨æt.deamon=True
ï¼è¿å¥çä½ç¨æ¯å½ä¸»çº¿ç¨éåºçæ¶åï¼è¯æµçº¿ç¨ä¹ä¸åéåºï¼ä¸å¨åå°ç»§ç»æ§è¡ã
æ¶è´¹è è·åä»»å¡åéè¦åä»ä¹å¤çï¼
å 为代ç ä¿åå¨æ°æ®åºï¼æ以é¦å è¦å°ä»£ç ä»æ°æ®åºååºæ¥ï¼ææ件类åå½ååä¿åå°ç¸åºçè¯å¤ç®å½ä¸ãç¶åå¨è¯å¤ç®å½ä¸å¯¹ä»£ç è¿è¡ç¼è¯ï¼å¦æç¼è¯é误åå°é误信æ¯ä¿åå°æ°æ®åºï¼è¿åç¼è¯é误ãç¼è¯éè¿åè¿è¡ç¨åºï¼æ£æµç¨åºæ§è¡æ¶é´åå åï¼è¯å¤ç¨åºæ§è¡ç»æã
å¦ä½ç¼è¯ä»£ç ï¼
æ ¹æ®ä¸åçç¼ç¨è¯è¨ï¼éæ©ä¸åçç¼è¯å¨ãæçè¯æµç¨åºæ¯æå¤ç§ç¼ç¨è¯è¨ãç¼è¯å®é ä¸å°±æ¯è°ç¨å¤é¨ç¼è¯å¨å¯¹ä»£ç è¿è¡ç¼è¯ï¼æ们éè¦è·åç¼è¯ä¿¡æ¯ï¼å¦æç¼è¯é误ï¼éè¦å°é误信æ¯ä¿åå°æ°æ®åºã
è°ç¨å¤é¨ç¨åºå¯ä»¥ä½¿ç¨pythonçsubprocess模åï¼è¿ä¸ªæ¨¡åé常强大ï¼æ¯os.system()ä»ä¹ççé¼å¤äºãéé¢æ个Popenæ¹æ³ï¼æ§è¡å¤é¨ç¨åºã设置shell=True
æ们就è½ä»¥shellæ¹å¼å»æ§è¡å½ä»¤ãå¯ä»¥ä½¿ç¨cwd
æå®å·¥ä½ç®å½ï¼è·åç¨åºçå¤é¨è¾åºå¯ä»¥ä½¿ç¨ç®¡éPIPEï¼è°ç¨communicate()
æ¹æ³å¯ä»¥å¯ä»¥è·åå¤é¨ç¨åºçè¾åºä¿¡æ¯ï¼ä¹å°±æ¯ç¼è¯é误信æ¯ã
å¯ä»¥æ ¹æ®ç¼è¯ç¨åºçè¿åå¼æ¥å¤æç¼è¯æ¯å¦æåï¼ä¸è¬æ¥è¯´ï¼è¿åå¼ä¸º0表示ç¼è¯æåã
æäºè¯è¨ï¼æ¯å¦ruby
åperl
æ¯è§£éåè¯è¨ï¼ä¸æä¾ç¼è¯é项ï¼å æ¤å¨è¿éä»
ä»
å ä¸-c
åæ°åç®åç代ç æ£æ¥ã
python
ï¼lua
ï¼java
çå¯ä»¥ç¼è¯æäºè¿å¶æ件ç¶å解éæ§è¡ã
ACMer们çéçä¸ä¸gcc
åg++
åpascal
çç¼è¯åæ°ï¼ä»¥ååç¨åºå¯ä»¥ä»¥è¿ä¸ªåæ°è¿è¡ç¼è¯ï¼åªè¦å¨æ¬å°ç¼è¯éè¿ä¸è¬å¨æå¡å¨ä¸ç¼è¯å°±ä¸ä¼åºç°ç¼è¯é误é®é¢ã
å¯è½æäºæåä¼æçé®ï¼ä¸ºä»ä¹å è¿ä¹å¤è¯è¨ï¼æ£å¼ACMæ¯èµåªè®©ç¨C
,C++
åJAVA
è¯è¨åï¼å¯¹è¿ä¸ªé®é¢ï¼æåªæ³è¯´ï¼å为ä¸ä¸ªå¨çº¿æµè¯ç³»ç»ï¼ä¸è½ä»
ä»
å±éå¨ACMä¸ãå¦æè½è®©åå¦è
ç¨è¿ä¸ªå¹³å°æ¥ç»ä¹ ç¼ç¨è¯è¨ä¸æ¯ä¹å¾å¥½ï¼åACMæ¯æ趣çï¼ç¨ä¸é¨æ°çè¯è¨å»åACMé¢ç®ä¹æ¯æ趣çï¼å¿«ä¹çå»å¦ä¹ ä¸é¨è¯è¨ä¸æ¯å¦å¾å¾å¿«ï¼ææ¿è®¤ï¼æ好å¤è¯è¨ä¸å¤ªéååACMï¼å 为ACM对æ¶é´åå
åè¦æ±æ¯è¾ä¸¥æ ¼ï¼å¥½å¤è§£éæ§è¡çè¯è¨å¯è½å å
åæ¯è¾å¤§ï¼è¿è¡é度æ¯è¾æ
¢ï¼åªè¦æ±çä¸ç§å¦ä¹ ç¼ç¨è¯è¨çå¿æå»å·é¢å°±å¥½äºãæ¤å¤ï¼å¯¹äºæ°å
´çgo
è¯è¨ï¼æ认为æ¯é常éåç¨æ¥åACMçãçé¼çhaskell
è¯è¨ä¹å¼å¾ä¸å¦ï¼æè¿°é«çº§æ°æ®ç»æä¹å¾æ¹ä¾¿ãæå
´è¶£çå¯ä»¥è¯è¯ã
æçè¯æµç¨åºæ¯å¯ä»¥æ©å±çï¼å¦ææ³åå å ¶ä»ç¼ç¨è¯è¨ï¼åªè¦ç¥éç¼è¯åæ°ï¼ç¥éå¦ä½æ§è¡ï¼é 置好ç¼è¯å¨åè¿è¡æ¶ç¯å¢ï¼å¨è¯æµç¨åºéé¢å ä¸å°±è½ç¼è¯åè¯æµã
def compile(solution_id,language):
'''å°ç¨åºç¼è¯æå¯æ§è¡æ件'''
build_cmd = {
"gcc" : "gcc main.c -o main -Wall -lm -O2 -std=c99 --static -DONLINE_JUDGE",
"g++" : "g++ main.cpp -O2 -Wall -lm --static -DONLINE_JUDGE -o main",
"java" : "javac Main.java",
"ruby" : "ruby -c main.rb",
"perl" : "perl -c main.pl",
"pascal" : 'fpc main.pas -O2 -Co -Ct -Ci',
"go" : '/opt/golang/bin/go build -ldflags "-s -w" main.go',
"lua" : 'luac -o main main.lua',
"python2": 'python2 -m py_compile main.py',
"python3": 'python3 -m py_compile main.py',
"haskell": "ghc -o main main.hs",
}
p = subprocess.Popen(build_cmd[language],shell=True,cwd=dir_work,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
out,err = p.communicate()#è·åç¼è¯é误信æ¯
if p.returncode == 0: #è¿åå¼ä¸º0,ç¼è¯æå
return True
dblock.acquire()
update_compile_info(solution_id,err+out) #ç¼è¯å¤±è´¥,æ´æ°é¢ç®çç¼è¯é误信æ¯
dblock.release()
return False
ç¨æ·ä»£ç å¨æ§è¡è¿ç¨ä¸æ¯å¦ä½è¿è¡è¯å¤çï¼ACMerå¿ çï¼ï¼
åé¢è¯´äºï¼å¦æåºç°ç¼è¯é误(Compile Error)ï¼æ¯ä¸ä¼æ§è¡çãæ¯ä¸ªé¢ç®é½æä¸ä¸ªæ åçæ¶é´åå
åéå¶ï¼ä¾å¦æ¶é´1000ms
ï¼å
å65536K
ï¼ç¨åºå¨æ§è¡çæ¶åä¼å®æ¶æ£æ¥å
¶è±è´¹æ¶é´å使ç¨å
åä¿¡æ¯ï¼å¦æåºç°è¶
æ¶åè¶
å
åå°ä¼åå«è¿åTime Limit Exceeded
åMemory Limit Exceeded
é误信æ¯ï¼å¦æç¨åºæ§è¡æ¶åºç°é误ï¼æ¯å¦éæ³æéï¼æ°ç»è¶ççï¼å°ä¼è¿åRuntime Error
ä¿¡æ¯ãå¦æä½ çç¨åºæ²¡æåºç°ä¸é¢çä¿¡æ¯ï¼è¯´æç¨åºé¡ºå©æ§è¡ç»æäºãæ¥ä¸æ¥ï¼å°±æ¯å¯¹ä½ çç¨åºçè¾åºä¹å°±æ¯è¿è¡ç»æè¿è¡æ£æ¥ï¼å¦æä½ çæ§è¡ç»æåæ们çæ åçæ¡å®å
¨ä¸æ ·ï¼åè¿åAccepted
ï¼ä¹å°±è¯´æä½ è¿ä¸ªé¢ç®å对äºãå¦æé¤å»ç©ºæ ¼ï¼æ¢è¡ï¼tabå¤å®å
¨ç¸åï¼å说æä½ ç代ç æ ¼å¼é误ï¼å°è¿åPresentation Error
ï¼å¦æä½ è¾åºçå
容æä¸é¨ååæ åçæ¡å®å
¨ä¸æ ·ï¼ä½æ¯è¿è¾åºäºä¸äºå
¶ä»å
容ï¼å说æä½ å¤è¾åºäºï¼è¿æ¶åå°è¿åOutput Limit Exceeded
é误信æ¯ï¼åºç°å
¶ä»æ
åµï¼å°±è¯´æä½ çè¾åºç»æåæ åçæ¡ä¸ä¸æ ·ï¼å°±æ¯Wrong Answer
äºã
æ»ç»ä¸ä¸é误çåºç°é¡ºåºï¼
Compile Error
-> Memory Limit Exceeded
= Time Limit Exceeded
= Runtime Error
-> Wrong Answer
-> Output Limit Exceeded
-> Presentation Error
-> Accepted
ç´æ¥è¯´é¾å æäºç©ºæ´ï¼åäºå¼ æµç¨å¾ï¼
å¦æä½ å¾å°äºå
¶ä»ä¿¡æ¯ï¼æ¯å¦System error
ï¼å说ææå¡å¨ç«¯å¯è½åºé®é¢äºï¼æ们ææ¯äººåä¼æ³æ³è§£å³ãå¦æçå°waiting
ï¼è¯´æçå¾
è¯æµç代ç æ¯è¾å¤ï¼ä½ éè¦ç¨ä½çå¾
ï¼ç´å°ä»£ç 被è¯æµãå¦æä½ å¾å°äºJudging
ç»æï¼è¯´æä½ ç代ç æ£å¨è¯æµï¼å¦æé¿æ¶é´ä¸ç´æ¯Judging
ï¼å说æè¯æµç¨åºå¨è¯æµè¿ç¨ä¸å¯è½åºé®é¢äºï¼æ²¡æè¯å¤åºç»æå°±åæ¢äºãææ¯äººåä¼ä¸ºä½ éå¤çã
å¸æACMer们è½æ ¹æ®ä¸é¢çè¯æµæµç¨ï¼å¨çå°èªå·±çè¯å¤ç»æçæ¶åï¼è½å¤åæåºä½ 离ACè¿æå¤è¿ï¼ä»¥åå¦ä½æ¹è¿ä½ ç代ç æè½ACã
è¯å¤çæ¡çé£é¨åæºç ï¼
def judge_result(problem_id,solution_id,data_num):
'''对è¾åºæ°æ®è¿è¡è¯æµ'''
currect_result = os.path.join(config.data_dir,str(problem_id),'data%s.out'%data_num)
user_result = os.path.join(config.work_dir,str(solution_id),'out%s.txt'%data_num)
try:
curr = file(currect_result).read().replace('\r','').rstrip()#å é¤\r,å é¤è¡æ«çç©ºæ ¼åæ¢è¡
user = file(user_result).read().replace('\r','').rstrip()
except:
return False
if curr == user: #å®å
¨ç¸å:AC
return "Accepted"
if curr.split() == user.split(): #é¤å»ç©ºæ ¼,tab,æ¢è¡ç¸å:PE
return "Presentation Error"
if curr in user: #è¾åºå¤äº
return "Output limit"
return "Wrong Answer" #å
¶ä»WA
注æä¸ä¸ï¼ä»£ç ä¸æ个replace('\r','')
æ¹æ³ï¼å®çä½ç¨å°±æ¯å°\r
æ¿æ¢æ空å符串ã为ä»ä¹è¦åè¿ä¸ªæ¿æ¢å¢ï¼å 为å¨windowsä¸ï¼ææ¬çæ¢è¡æ¯"\r\n"
,èå¨Linuxä¸æ¯"\n"
ãå 为ä¸è½ç¡®å®æµè¯æ°æ®æ¥æºä¸windowsè¿æ¯Linuxï¼å¢å ä¸ä¸ª\r
ï¼å°±æ¯å¢å ä¸ä¸ªå符ï¼å¦æä¸å é¤çè¯ï¼ä¸¤ä¸ªææ¬å°±æ¯ä¸ä¸æ ·çï¼å°±ä¼é æwrong answer
ç»æãæè®¸ä½ æ¾ç»éå°è¿å¨windowsä¸ç¨è®°äºæ¬æå¼ä¸ä¸ªçº¯ææ¬æ件ï¼æ ¼å¼å
¨ä¹±äºï¼ææææ¬é½å¨ä¸è¡å
ï¼é常影åé
读ãä½ å¯ä»¥éè¿ç¨ååæ¿æå¼æ¥è§£å³è¿ä¸ªé®é¢ãæ®è¯´"\r\n"
æ¥æºäºæ¯è¾å¤èçæå°æºï¼æ¯æå°å®ä¸è¡ï¼é½è¦å
âå车(\r)â
ï¼åâæ¢è¡â(\n)
ãåæ ·ä¸ä¸ªCè¯è¨çprintf("\n")
å½æ°ï¼å¨windowsä¸å°çæ"\r\n"
ï¼èå¨Linuxä¸çæ"\n"
ï¼å 为è¯æµç¨åºä¸ºä½ èªå¨å¤çäºï¼å æ¤ä½ å°±ä¸å¿
å
³æ³¨è¿äºç»èçä¸è¥¿äºã
è¯æµç¨åºæ¯å¦ä½æ£æµä½ çç¨åºçæ§è¡æ¶é´åå åçï¼
è¿ä¸ªé®é¢å°æ°äºæå¥½ä¹ ï¼ä¹æ¥äºå¥½å¤èµæã
ç¨æ·çç¨åºè¦å¨æå¡å¨ä¸æ§è¡ï¼é¦å ä¸è½è®©ç¨æ·çç¨åºæ éç³è¯·å åï¼å¦å容æé ææ»æºç°è±¡ï¼éè¦å°ç¨åºçå åéå¶å¨é¢ç®è§å®çæ大å åå ãå ¶æ¬¡è¦éå¶ç¨æ·ç¨åºçæ§è¡æ¶é´ï¼ä¸è½è®©ç¨æ·çç¨åºæ éå¶è¿è¡ã
ä¸è¬è§£å³æ¹æ¡æ¯ï¼å¨ç¨æ·çç¨åºæ§è¡åï¼å å好èµæºéå¶ï¼éå¶ç¨åºè½ä½¿ç¨çæ大å ååCPUå ç¨ï¼å½ç¨æ·çç¨åºä¸æ¦è¶ åºéå¶å°±èªå¨ç»æ¢äºãè¿æ个æ¯è¾éè¦çé®é¢æ¯å¦ä½è·åç¨åºæ§è¡æé´çæ大å åå ç¨çãç¨æ·ç代ç å¨æ§è¡åéè¦ç³è¯·å åï¼æ§è¡æé´è¿è½å¨æç³è¯·åéæ¾å åï¼æ§è¡å®æ¯éæ¾å åãç¨åºæ§è¡æ¶è¿æå¯è½ä½¿ç¨æéçåºå±æä½ï¼è¿æ çç»æ£æµå åé ææ´å¤§çå°é¾ãå¨windowsä¸ï¼ç¨åºæ§è¡ç»æåï¼å¯ä»¥è°ç¨ç³»ç»å½æ°è·åç¨åºæ§è¡æé´çæ大å åï¼è²ä¼¼å¨Linuxä¸æ²¡ç¨ç°æçå½æ°å¯ä»¥è°ç¨ã
å¨Linuxä¸ï¼æ们å¯ä»¥ä½¿ç¨ps
ætop
å½ä»¤æ¥è·åæçè§å¨æ个æ¶å»åºç¨ç¨åºçå
åå ç¨çï¼è¦è·åç¨åºçæ大æ§è¡å
åï¼å°±è¦ä¸æå»æ£æµï¼ä¸æå»æ¯è¾ï¼ç´å°ç¨åºç»æï¼è·åæ大å¼å°±æ¯ç¨æ·ç¨åºæ§è¡æé´çæ大å
åãæ ¹æ®è¿ä¸ªè®¾æ³ï¼æåäºä¸ä¸ªç¨åºæ¥å®ç°è¿ä¸ªæ³æ³ï¼
def get_max_mem(pid):
'''è·åè¿ç¨å·ä¸ºpidçç¨åºçæ大å
å'''
glan = psutil.Process(pid)
max = 0
while True:
try:
rss,vms = glan.get_memory_info()
if rss > max:
max = rss
except:
print "max rss = %s"%max
return max
def run(problem_id,solution_id,language,data_count,user_id):
'''è·åç¨åºæ§è¡æ¶é´åå
å'''
time_limit = (time_limit+10)/1000.0
mem_limit = mem_limit * 1024
max_rss = 0
max_vms = 0
total_time = 0
for i in range(data_count):
'''ä¾æ¬¡æµè¯åç»æµè¯æ°æ®'''
args = shlex.split(cmd)
p = subprocess.Popen(args,env={"PATH":"/nonexistent"},cwd=work_dir,stdout=output_data,stdin=input_data,stderr=run_err_data)
start = time.time()
pid = p.pid
glan = psutil.Process(pid)
while True:
time_to_now = time.time()-start + total_time
if psutil.pid_exists(pid) is False:
program_info['take_time'] = time_to_now*1000
program_info['take_memory'] = max_rss/1024.0
program_info['result'] = result_code["Runtime Error"]
return program_info
rss,vms = glan.get_memory_info()
if p.poll() == 0:
end = time.time()
break
if max_rss < rss:
max_rss = rss
print 'max_rss=%s'%max_rss
if max_vms < vms:
max_vms = vms
if time_to_now > time_limit:
program_info['take_time'] = time_to_now*1000
program_info['take_memory'] = max_rss/1024.0
program_info['result'] = result_code["Time Limit Exceeded"]
glan.terminate()
return program_info
if max_rss > mem_limit:
program_info['take_time'] = time_to_now*1000
program_info['take_memory'] = max_rss/1024.0
program_info['result'] =result_code["Memory Limit Exceeded"]
glan.terminate()
return program_info
logging.debug("max_rss = %s"%max_rss)
# print "max_rss=",max_rss
logging.debug("max_vms = %s"%max_vms)
# logging.debug("take time = %s"%(end - start))
program_info['take_time'] = total_time*1000
program_info['take_memory'] = max_rss/1024.0
program_info['result'] = result_code[program_info['result']]
return program_info
ä¸é¢çç¨åºç¨å°äºä¸äºè¿ç¨æ§å¶çä¸äºç¥è¯ï¼ç®å说æä¸ä¸ã
ç¨åºçåºæ¬åçæ¯ï¼å ç¨å¤è¿ç¨åºsubprocessçPopenå½æ°å»å建ä¸ä¸ªæ°çè¿ç¨ï¼è·åå ¶è¿ç¨å·(pid)ï¼ç¶åç¨ä¸»çº¿ç¨å»çæµè¿ä¸ªè¿ç¨ï¼ä¸»è¦æ¯çæµå®æ¶çå åä¿¡æ¯ãéè¿æ¯è¾å½æ°ï¼è·å¾ç¨åºçæ§è¡æé´çæ大å åãä»ä¹æ¶ååæ¢å¢ï¼æåç§æ åµï¼
- ç¨åºè¿è¡å®æ£å¸¸ç»æãè¿ä¸ªæ们å¯ä»¥éè¿ subprocess.Popenéé¢çpollæ¹æ³æ¥æ£æµï¼å¦æ为0,å代表ç¨åºæ£å¸¸ç»æã
- ç¨åºæ§è¡æ¶é´è¶ è¿äºè§å®çæ大æ§è¡æ¶é´ï¼ç¨terminateæ¹æ³å¼ºå¶ç¨åºç»æ¢
- ç¨åºæ§è¡å åè¶ è¿äºè§å®çæ大å åï¼terminate强å¶ç»æ¢ã
- ç¨åºæ§è¡æé´åºç°é误ï¼å¼å¸¸éåºäºï¼è¿æ¶åæ们éè¿æ£æ¥è¿ä¸ªpidçæ¶åå°±ä¼åç°ä¸åå¨ã
è¿æä¸ç¹æ¯å¼å¾æ³¨æçï¼ä¸ææå°å¨ç¼è¯ç¨åºçæ¶åï¼è°ç¨subprocess.Popen
ï¼æ¯éè¿shellæ¹å¼è°ç¨çï¼ä½æ¯è¿é没æ使ç¨è¿ç§æ¹å¼ï¼ä¸ºä»ä¹å¢ï¼è¿ä¸¤ç§æ¹å¼æä»ä¹åºå«ï¼æ大çåºå«å°±æ¯è¿åçè¿ç¨çpidï¼ä»¥shellæ¹å¼æ§è¡ï¼è¿åçpid并ä¸æ¯åè¿ç¨ççæ£pidï¼èæ¯shellçpidï¼å½æ们å»æ£æ¥è¿ä¸ªpidçå
å使ç¨ççæ¶åå¾å°ç并ä¸æ¯ç¨æ·è¿ç¨çpidï¼ä¸éè¿shellæ¹å¼å»è°ç¨å¤é¨ç¨åºåæ¯ç´æ¥è¿åçæ£ç¨åºçpidï¼èä¸ç¨å»è°ç¨shellãå®æ¹ææ¡£æ¯è¿ä¹è¯´çï¼if shell is true, the specified command will be executed through the shell.
å¦æä¸ç¨shellæ¹å¼å»æ§è¡å½ä»¤çè¯ï¼ä¼ éåæ°çæ¶åå°±ä¸è½ç´æ¥å°åç¬¦ä¸²ä¼ éè¿å»ï¼ä¾å¦ls -l
è¿ä¸ªå½ä»¤ls
ååæ°-l
ï¼å½shell=False
æ¶ï¼éè¦å°å½ä»¤ååæ°åæä¸ä¸ªå表['ls','-l']
ä¼ éè¿å»ãå½åæ°æ¯è¾å¤æçæ¶åï¼å°å½ä»¤åéæå表就æ¯è¾éº»ç¦ï¼å¹¸å¥½python为æ们æä¾äºshlex
模åï¼éé¢çsplitæ¹æ³å°±æ¯ä¸é¨ç¨æ¥åè¿ä¸ªçï¼å®æ¹ææ¡£æ¯è¿ä¹è¯´çï¼Split the string s using shell-like syntax.
ï¼æ好ä¸è¦èªå·±å»è½¬æ¢ï¼æå¯è½ä¼å¯¼è´é误èä¸è½æ§è¡ã
ä¸é¢çæ£æµå ååæ¶é´çæ¹æ³é è°±åï¼
ä¸é è°±ï¼ç¸å½ä¸é è°±ï¼ï¼å½ç¶å¦å¦pythonå¦ä½å¯¹è¿ç¨æ§å¶ä¹æ²¡åå¤åï¼ï¼ä¸ºä»ä¹å¢ï¼æç¹ç»éªçé½ç¥éï¼Cè¯è¨çè¿è¡æçæ¯pythoné«åï¼æ§è¡é度æ¯pythonå¿«ï¼è¿ä¼é æä»ä¹åæï¼ä¸ä¸ªç®åçhello world
å°ç¨åºï¼Cè¯è¨âç¬é´âå°±æ§è¡å®äºï¼è¿æ²¡çæçpythonç¨åºå¼å§æ£æµå°±æ§è¡å®äºï¼æçè¯æµç¨åºä»ä¹é½æ²¡æ£æµå°ï¼ç¶åè¿å0ï¼åå°çç¨åºå
åä¹ä¸å¯è½æ¯0åï¼å¨OJä¸æ¾ç¤ºå
å为0ç¸å½ä¸ç§å¦ï¼
é£æä¹åï¼è½ä¸è½è®©Cè¯è¨çç¨åºæ§è¡é度æ
¢ä¸æ¥ï¼CPUçé¢çæ¯åºå®çï¼æ们没æ³ä¸é¨æ¯ä¸ä¸ªç¨åºçå ç¨çCPUé¢çéä½ï¼å¨windowsä¸åæ¯æåé齿轮
è¿æ¬¾è½¯ä»¶å¯ä»¥è®©è½¯ä»¶æ§è¡é度åæ
¢
ï¼ä¸ç¥éå¨Linux
ä¸æ没æãè¿æ没æå
¶ä»åæ³ï¼èªæçä½ ä¹è®¸ä¼æ³å°gdb
è°è¯ï¼æä¹æ¾ç»æ³ç¨è¿ç§æ¹æ³ï¼ç¨gdbè°è¯å¯ä»¥ä½¿ç¨åºåæ¥æ§è¡ï¼ç¶åç¨åºæ§è¡ä¸æ¥ï¼ææ£æµä¸æ¬¡ï¼å¤å¥½ï¼å¤å®ç¾ï¼ç 究äºå¥½ä¸éµågdbï¼åç°å¹¶ä¸æ¯é£ä¹ç®åãé¦å
ï¼æ们以åç¨gdbè°è¯C/C++çæ¶åï¼å¨ç¼è¯çæ¶åè¦å ä¸ä¸ä¸ª-g
åæ°ï¼ç¶åæ§è¡çæ¶åå¯ä»¥åæ¥æ§è¡ï¼æ¤å¤ï¼è¿æ设置æç¹ä»ä¹çãæå 个é®é¢ï¼
- å ¶ä»è¯è¨å¦ä½è°è¯ï¼æ¯å¦javaï¼è§£éæ§è¡çï¼ç´æ¥è°è¯javaèææºåï¼
- å¦ä½éè¿python对gdbè¿è¡æ§å¶ï¼è¿æè·åæ§è¡ç¶æçä¿¡æ¯ã
è¿äºé®é¢é½ä¸æ¯å¾å¥½è§£å³ã
é£ä¸é¢çæ¹æ³æµéçæ¶é´ååï¼ä¸åï¼ä¸ºä»ä¹ï¼æ们说çç¨åºçæ§è¡æ¶é´ï¼ä¸¥æ ¼æ¥è¯´æ¯å ç¨CPUçæ¶é´ãå 为CPUéç¨çæ¯è½®è½¬æ¶é´çæºå¶ï¼å¨æ个æ¶å»ï¼CPUå¨å¿å«çç¨åºãä¸é¢çæ¹æ³ç¨ç¨åºæ§è¡çç»ææ¶é´åå»å¼å§æ¶é´ï¼å¾å°çæ¶é´ä¸å®æ¯å®å®é æ§è¡çæ¶é´è¦å¤§ãå¦æç¨åºæ§è¡é度è¿å¿«ï¼ä¸å°1毫ç§ï¼è¯æµç¨åºä¹ä¸è½æ£æµåºæ¥ï¼ç´æ¥è¿å0äºã
å¦ä½è§£å³æ¶é´åå åçæµéé®é¢ï¼
åæ¥å¨v2ex
ä¸åäºä¸ä¸ªå¸åæé®ï¼å¾å°é«äººæç¹ï¼ä½¿ç¨lorun
ãlorun
æ¯githubä¸çä¸ä¸ªå¼æºé¡¹ç®ï¼é¡¹ç®å°åï¼https://github.com/lodevil/Lo-runnerï¼è¿æ¯ç¨Cè¯è¨åçä¸ä¸ªpythonæ©å±æ¨¡åï¼è®©ç¨åºå¨ä¸ä¸ªç±»ä¼¼æ²ççç¯å¢ä¸æ§è¡ï¼ç¶åç²¾åçè·åç¨åºçæ§è¡æ¶é´åå
åï¼è¿è½å¯¹ç¨åºè¿è¡éå¶ï¼éå¶ç¨åºçç³»ç»è°ç¨ãåææ¯è¿ä¹è¯´çï¼We use this python-c library to run program in a sandbox-like environment. With it, we can accurately known the resource using of the program and limit its resource using including system-call interrupt.
ãå®è£
使ç¨é½é常æ¹ä¾¿ãæ主è¦ç¨å®æ¥æµéæ§è¡æ¶é´åå
åï¼åæ代ç æ£æ¥è¿æ¯ç¨æçç¨åºã
æå ´è¶£çåå¦å¯ä»¥å°è¿ä¸ªæ¨¡åä¸è½½ä¸æ¥ï¼ä½ä¸ºæ¬å°æµè¯ä½¿ç¨ï¼å¯ä»¥é¢å çæä¸äºæµè¯æ°æ®ï¼ç¶åæµéä½ ç代ç çæ§è¡æ¶é´åå åï¼æ¯å¯¹ä½ ççæ¡æ¯å¦æ£ç¡®ã
ä¸åç¼ç¨è¯è¨æ¶é´å åå¦ä½éå®ï¼
ä¸è¬æ¥è¯´ï¼å设C/C++è¯è¨çæ ç¨æ¯æ¶é´éå¶ï¼1000ms,å åéå¶32768Kï¼é£ä¹javaçæ¶é´åå åéå¶é½æ¯æ åéå¶ç2åï¼å³2000msï¼65536Kã
ç±äºåæ¥æåOJå¢å äºå¥½å¤å
¶ä»è¯è¨ï¼ææ¯è¿æ ·è§å®çï¼ç¼è¯åçè¯è¨åé度è¾å¿«ç解éåè¯è¨çæ¶é´åå
åéå¶åC/C++æ¯ä¸æ ·çï¼è¿æ ·çè¯è¨å
æ¬ï¼CãC++ãgoãhaskellãluaãpascal
ï¼å
¶ä»é度ç¨æ
¢ç解éæ§è¡çè¯è¨åJAVAæ¯ä¸æ ·çï¼å
æ¬ï¼javaãpython2ãpython3ãrubyãperl
ãæ¯ç«ä½¿ç¨é¤Cï¼C++ï¼JAVAå¤çè¯è¨çæåæ¯ç«æ¯å°æ°ï¼å¦æéå¶å¤ªä¸¥æ ¼çè¯å¯ä»¥æ ¹æ®å®é
æ
åµå¯¹å
¶ä»ç¼ç¨è¯è¨æ¾å®½éå¶ã
å¤ç»æµè¯æ°æ®çé¢ç®æ¶é´åå åå¦ä½æµç®ï¼
å¤ç»æµè¯æ°æ®æ¯ä¸ç»ä¸ç»ä¾æ¬¡æ§è¡ï¼æ¶é´åå åååç»çæ大å¼ï¼ä¸æ¦æç»æµè¯æ°æ®æ¶é´åå åè¶ åºéå¶ï¼åç»æ¢ä»£ç æ§è¡ï¼è¿åè¶ æ¶æè¶ å åé误信æ¯ã
å¦ä½é²æ¢æ¶æ代ç ç ´åç³»ç»ï¼
æ们å¯ä»¥ä½¿ç¨ä»¥ä¸ææ¯æ¥å¯¹ç¨æ·ç¨åºè¿è¡éå¶ï¼
-
lorun
模åæ¬èº«å°±æéå¶ï¼é²æ¢å¤é¨è°ç¨ - éä½ç¨åºçæ§è¡æéãå¨Linuxä¸ï¼ç®å½æéä¸è¬ä¸º
755
ï¼ä¹å°±æ¯è¯´ï¼å¦ææ¢æä¸ä¸ªå«çç¨æ·ï¼åªè¦ä¸æ¯ææè ï¼å°±æ²¡æä¿®æ¹åå é¤çæéãpythonéé¢å¯ä»¥ä½¿ç¨os.setuid(int(os.popen("id -u %s"%"nobody").read()))
æ¥å°ç¨åºä»¥nobody
ç¨æ·ç身份æ§è¡ - 设置æ²çç¯å¢ï¼å°ç¨æ·æ§è¡ç¯å¢åå¤é¨é离ãLinuxä¸çchrootå½ä»¤å¯ä»¥å®ç°ï¼pythonä¹æç¸å
³æ¹æ³ï¼ä½æ¯éè¦æåæ建æ²çç¯å¢ãç¨
jailkit
å¯ä»¥å¿«éæ建æ²çç¯å¢ï¼æå ´è¶£çæåå¯ä»¥çç - 使ç¨
ACL访é®æ§å¶å表
è¿è¡è¯¦ç»æ§å¶ï¼è®©nobody
ç¨æ·åªæ对æ个æ件夹ç读åæéï¼å ¶ä»æ件夹ç¦æ¢è®¿é® - è¯å¤æºåæå¡å¨å离ï¼æ¾åç¬çæºå¨ï¼åªè´è´£è¯å¤
- 对ç¨æ·æ交ç代ç é¢å
æ£æ¥ï¼åç°æ¶æ代ç ç´æ¥è¿å
Runtime Error
- ç¦æ¢è¯æµæå¡å¨è¿æ¥å¤ç½ï¼æè éè¿é²ç«å¢éå¶ç½ç»è®¿é®
å¦ä½å¯å¨ååæ¢è¯æµç¨åºä»¥åå¦ä½è®°å½é误æ¥å¿ï¼
å¯å¨å¾ç®åï¼åªè¦ç¨pythonæ§è¡protect.py
å°±è¡äºã
å¦æéè¦åå°æ§è¡çè¯å¯ä»¥ä½¿ç¨Linuxä¸çnohup
å½ä»¤ã
为äºé²æ¢åæ¶å¼å¯å¤ä¸ªè¯æµç¨åºï¼éè¦å°ä»¥åå¼å¯çè¯æµç¨åºå ³éã
为äºæ¹ä¾¿å¯å¨ï¼æåäºè¿æ ·ä¸ä¸ªå¯å¨èæ¬ï¼
#!/bin/bash
sudo kill `ps aux | egrep "^nobody .*? protect.py" | cut -d " " -f4`
sudo nohup python protect.py &
第ä¸æ¡å½ä»¤å°±æ¯ææ»å¤ä½çè¯æµè¿ç¨ï¼ç¬¬äºæ¡æ¯å¯å¨è¯æµç¨åºã
å¨ç¨åºéé¢ä½¿ç¨äºlogging模åï¼æ¯ä¸é¨ç¨æ¥è®°å½æ¥å¿çï¼è¿ä¹æ¨¡åå¾å¥½ç¨ï¼ä¹å¾å¼ºå¤§ï¼å¯å®å¶æ§å¾å¼ºï¼å¯¹æ们åæç¨åºæ§è¡ç¶ææå¾å¤§å¸®å©ãä¸é¢æ¯ä¸äºç¤ºä¾ï¼
2013-03-07 18:19:04,855 --- 321880 result 1
2013-03-07 18:19:04,857 --- judging 321882
2013-03-07 18:19:04,881 --- judging 321883
2013-03-07 18:19:04,899 --- judging 321884
2013-03-07 18:19:04,924 --- 321867 result 1
2013-03-07 18:19:04,950 --- 321883 result 7
2013-03-07 18:19:04,973 --- 321881 result 1
2013-03-07 18:19:05,007 --- 321884 result 1
2013-03-07 18:19:05,012 --- 321882 result 4
2013-03-07 18:19:05,148 --- judging 321885
2013-03-07 18:19:05,267 --- judging 321886
2013-03-07 18:19:05,297 --- judging 321887
2013-03-07 18:19:05,356 --- judging 321888
2013-03-07 18:19:05,386 --- judging 321889
2013-03-07 18:19:05,485 --- 321885 result 1
pythonçé ç½®æ件å¦ä½ç¼åï¼
æç®åææçæ¹å¼å°±æ¯å»ºç«ä¸ä¸ªconfig.py
æ件ï¼éé¢åä¸é
ç½®çå
容ï¼å°±åä¸é¢ä¸æ ·ï¼
#!/usr/bin/env python
#coding=utf-8
#å¼å¯è¯æµçº¿ç¨æ°ç®
count_thread = 4
#è¯æµç¨åºéå容é
queue_size = 4
#æ°æ®åºå°å
db_host = "localhost"
#æ°æ®åºç¨æ·å
db_user = "user"
#æ°æ®åºå¯ç
db_password = "password"
#æ°æ®åºåå
db_name = "db_name"
使ç¨çæ¶ååªéè¦å°è¿ä¸ªæ件导å
¥ï¼ç¶åç´æ¥config.queue_size
å°±å¯ä»¥è®¿é®é
ç½®æ件éé¢çå
容ï¼å¾æ¹ä¾¿çã
è¯æµç¨åºçè¯æµæçå¦ä½ï¼
èªä»æå¡å¨å¯ç¨æ°çè¯æµç¨åºä¹åï¼å·²ç»ç»åäºä¸¤æ¬¡å¤§çæ¯èµåå 次大åèè¯ï¼å¨å ç¾ä¸ªäººçæ¯èµåèè¯ä¸ï¼è¯æµåºæ¬æ²¡ç¨çå¾ ç°è±¡ï¼ç¨æ·æ交ç代ç åºæ¬é½è½ç«å³è¯æµåºæ¥ã大ä½æµäºä¸ä¸ï¼åæå¡å¨å¹³åæ¯ç§è½å¤6个é¢ç®å·¦å³ï¼å æ¬è·å代ç ï¼ç¼è¯ï¼è¿è¡ï¼æ£æµï¼æ°æ®åºåå ¥ç»æçæµç¨ï¼ãè¯æµç¨åºç®åå·²ç»ç¨³å®è¿è¡äºå 个æï¼æ²¡æåºç°å¤§çé®é¢ï¼åºè¯¥è¯´ææ¯æ¯è¾æçäºã
è¯æµç¨åºè¿è½ç»§ç»æ¹è¿åï¼
å½æ¶èå估计æ¯è¢«é©´è¸¢äºï¼å±
ç¶ä½¿ç¨å¤çº¿ç¨æ¥è¯æµï¼æç»éªçpythonç¨åºç¿é½ç¥éï¼pythonæ个å
¨å±GIL
éï¼è¿ä¸ªéä¼å°pythonçå¤ä¸ªçº¿ç¨åºååï¼å¨ä¸ä¸ªæ¶å»åªå
许ä¸ä¸ªçº¿ç¨æ§è¡ï¼æ è®ºä½ çæºå¨æå¤å°ä¸ªCPUï¼åªè½ä½¿ç¨ä¸ä¸ªï¼è¿å°±ææ¾å½±åè¯æµé度ï¼å¦ææ¢æå¤è¿ç¨æ¹å¼ï¼ä¸ä¸ªè¯æµè¿ç¨å ç¨ä¸ä¸ªCPUæ ¸å¿ï¼è¯æµé度å°ä¼æ¯å åå ååçæ§è½æåï¼å°æ¶åå¼ä¸ªä¸å人çæ¯èµä¼°è®¡é®é¢ä¹ä¸å¤§ï¼æèµ·ç è¯æµé度è½ä¿è¯ã
æ¤å¤ï¼è¿å¯ä»¥æ建ä¸ä¸ªåå¸å¼çè¯æµæå¡å¨é群ï¼å¤§ä½è®¾æ³äºä¸ä¸å¯ä»¥è¿æ ·å®ç°ï¼
é¦å ï¼å¯ä»¥éä¸å°æå¡å¨Aä¸é¨åæ°æ®åºäº¤äºï¼å æ¬ä»æ°æ®åºä¸è·åè¯æµä»»å¡ä»¥åè¯æµç»æå°ç»æååæ°æ®åºãç¶åéæ©Nå°æ®é计ç®æºä½ä¸ºè¯æµæºï¼è¯æµæºåªåæ°æ®åºAæ交éï¼ä¹å°±æ¯ä»æå¡å¨Aè·åä»»å¡ï¼å¨æ®éæºå¨ä¸è¯æµï¼è¯æµå®åå°ç»æåé¦å°æå¡å¨Aï¼åç±Aå°ç»æåå ¥å°æ°æ®åºãæå¡å¨Aå¨è¿éå°±å å½ä¸ä¸ªä»»å¡ç®¡çååé çè§è²ï¼åè°å个è¯æµæºå»è¯æµãè¿æ ·å¯ä»¥åå°å¯¹æ°æ®åºçæä½ï¼è¯æµæºå°±ä¸ç¨å»ä¸éä¸éæ«æ°æ®åºäºãè¯æµçé度åå®å ¨æ§å¯ä»¥å¾å°è¿ä¸æ¥æåã
å ¶ä»
- ä¸é¢çç¨åºåæ¹æ³ä» ä¾å¦ä¹ åç 究ç¨ï¼ä¸¥ç¦ä»»ä½éæ³ç¨é
- æ¬äººå¦è¯æéï¼å¦æé误欢è¿æ¹è¯ææ£