質問編集履歴

2 タグの変更

namnium1125

namnium1125 score 2021

2017/09/09 01:18  投稿

python3 http.serverにおけるThreading
お世話になります。
[以前質問しましたこと](https://teratail.com/questions/90831)を解決する為にいろいろ取り組んでいたのですが、また壁に当たってしまい、もう一度、少し内容を変えて質問させていただきます。ご了承ください。
前回の質問に書いた通り、時間のかかる処理の経過をプログレスバーを表示したいです。
その為に調べていると[はてな](http://q.hatena.ne.jp/1374836016)の方に解決方法っぽいことが書いてありましたので、その通りに取り組んでいました。
ただDjangoに取り組んだことがなく、またすでにhttp.serverのほうでプログラムを組んでしまっていたため(個人使用なのでサーバーとしては十分です。)、cron、celeryではなくデータベースを利用する方法を考えました。
最終的には画像のようにすればいいのかなと思いました。
![イメージ説明](3cd6f7df26d320721d57deaca50c2884.jpeg)
しかしThreadingでmain.pyを動かしても、インタラクティブモードのときと違い結局main.pyが完了するまで結果が返されず、またos.systemで無理矢理main.pyを動かしても同様でした。
サーバー上でmain.pyの処理をcount.pyから切り離すというのは無理なんでしょうか?
PHPはよくわからないのですが、PHPにあるexec関数みたいなものはpythonにはないのでしょうか?
結局Djangoとceleryを使うしか無いのでしょうか?
以下私が書いてみたコードです。一部前回の質問と同じですが再掲します。
ただ試行錯誤の末ちょっとごちゃごちゃしてしまっています。。
/
├── cgi-bin
│   ├── count.mdb
│   ├── count.py
│   ├── main.py
│   └── reset.py (dbリセット用。本件に関係無し)
├── index.html
└── server.py
index.html
```lang-html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Progress By Ajax</title>
<script>
var request = new XMLHttpRequest();
var progress;
var percent;
var disp1;
var disp2;
var start;
var url = "/cgi-bin/count.py";
var rT = 0;
if(request){
window.addEventListener("load",function(e){
progress = document.getElementById("prog");
//↓最終的にはこっちで出力したい
percent = document.getElementById("percent");
start = document.getElementById("start");
//↓とりあえずこっちに出力
disp1 = document.getElementById("disp1");
disp2 = document.getElementById("disp2");
start.addEventListener("click",function(e){
request.open("GET",url,true);
request.onreadystatechange = sub;
request.send(null);
},false);
},false);
}
function sub(){
disp1.innerHTML = "readyState : " + request.readyState + "<br />status : " + request.status;
rT = request.responseText!="" ? request.responseText : rT;
disp2.innerHTML = rT;
console.log("requestText : " + rT);
var i = rT.isNaN ? 10 : parseInt(rT);
if(i<10&&request.readyState==4){
request.open("GET",url,true);
request.onreadystatechange = sub;
request.send(null);
}
}
</script>
</head>
<body>
<progress max="100" value="0" id="prog"></progress>
<span id="percent">0</span>%
<br />
<button id="start">start</button>
<br />
<br />
<div id="disp1"></div>
<br />
<br />
<div id="disp2"></div>
</body>
</html>
```
server.py
```lang-python
import http.server
import traceback
try:
server_address = ("", 8000)
handler_class = http.server.CGIHTTPRequestHandler
handler_class.cgi_directories = ["/cgi-bin"]
server = http.server.HTTPServer(server_address, handler_class)
server.serve_forever()
except:
traceback.print_exc()
```
cgi-bin/count.py
```lang-python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3
from time import sleep
import traceback
import threading
import os
import main
class MainThread(threading.Thread):
def run(self):
main.main()
def count():
print("Content-type: text/html;charset=utf-8\n")
try:
connection = sqlite3.connect("./cgi-bin/count.mdb")
cursor = connection.cursor()
cursor.execute("SELECT count FROM table1;")
count = cursor.fetchall()[0][0]
connection.commit()
cursor.close()
except Exception:
traceback.print_exc()
sleep(1)
if count == 0:
connection = sqlite3.connect("./cgi-bin/count.mdb")
cursor = connection.cursor()
cursor.execute("UPDATE table1 SET count = 1;")
connection.commit()
cursor.close()
T = MainThread()
T.start()
#os.system("python3 ./cgi-bin/main.py")
print(count)
elif count < 10:
print(count)
elif count >= 10:
print("<span>done</span>")
connection = sqlite3.connect("./cgi-bin/count.mdb")
cursor = connection.cursor()
cursor.execute("UPDATE table1 SET count = 0;")
connection.commit()
cursor.close()
count()
```
cgi-bin/main.py
```lang-python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3
from time import sleep
def main():
for i in range(10):
connection = sqlite3.connect("./cgi-bin/count.mdb")
cursor = connection.cursor()
cursor.execute("SELECT count FROM table1;")
count = cursor.fetchall()[0][0]
cursor.execute("UPDATE table1 SET count = ?;",(count+1,))
connection.commit()
cursor.close()
sleep(1)
if __name__ == "__main__":
main()
```
回答よろしくお願いします。m(_ _)m
  • Ajax

    2139 questions

    Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

  • Python 3.x

    18171 questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

  • JavaScript

    35698 questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Python

    33033 questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

1 パスの訂正

namnium1125

namnium1125 score 2021

2017/09/09 01:16  投稿

python3 http.serverにおけるThreading
お世話になります。
[以前質問しましたこと](https://teratail.com/questions/90831)を解決する為にいろいろ取り組んでいたのですが、また壁に当たってしまい、もう一度、少し内容を変えて質問させていただきます。ご了承ください。
前回の質問に書いた通り、時間のかかる処理の経過をプログレスバーを表示したいです。
その為に調べていると[はてな](http://q.hatena.ne.jp/1374836016)の方に解決方法っぽいことが書いてありましたので、その通りに取り組んでいました。
ただDjangoに取り組んだことがなく、またすでにhttp.serverのほうでプログラムを組んでしまっていたため(個人使用なのでサーバーとしては十分です。)、cron、celeryではなくデータベースを利用する方法を考えました。
最終的には画像のようにすればいいのかなと思いました。
![イメージ説明](3cd6f7df26d320721d57deaca50c2884.jpeg)
しかしThreadingでmain.pyを動かしても、インタラクティブモードのときと違い結局main.pyが完了するまで結果が返されず、またos.systemで無理矢理main.pyを動かしても同様でした。
サーバー上でmain.pyの処理をcount.pyから切り離すというのは無理なんでしょうか?
PHPはよくわからないのですが、PHPにあるexec関数みたいなものはpythonにはないのでしょうか?
結局Djangoとceleryを使うしか無いのでしょうか?
以下私が書いてみたコードです。一部前回の質問と同じですが再掲します。
ただ試行錯誤の末ちょっとごちゃごちゃしてしまっています。。
/
├── cgi-bin
│   ├── count.mdb
│   ├── count.py
│   ├── main.py
│   └── reset.py (dbリセット用。本件に関係無し)
├── index.html
└── server.py
index.html
```lang-html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Progress By Ajax</title>
<script>
var request = new XMLHttpRequest();
var progress;
var percent;
var disp1;
var disp2;
var start;
var url = "/cgi-bin/count.py";
var rT = 0;
if(request){
 window.addEventListener("load",function(e){
   progress = document.getElementById("prog");
   //↓最終的にはこっちで出力したい
   percent = document.getElementById("percent");
   start = document.getElementById("start");
   //↓とりあえずこっちに出力
   disp1 = document.getElementById("disp1");
   disp2 = document.getElementById("disp2");
   start.addEventListener("click",function(e){
     request.open("GET",url,true);
     request.onreadystatechange = sub;
     request.send(null);
   },false);
 },false);
}
function sub(){
 disp1.innerHTML = "readyState : " + request.readyState + "<br />status : " + request.status;
 rT = request.responseText!="" ? request.responseText : rT;
 disp2.innerHTML = rT;
 
 console.log("requestText : " + rT);
 var i = rT.isNaN ? 10 : parseInt(rT);
 if(i<10&&request.readyState==4){
   request.open("GET",url,true);
   request.onreadystatechange = sub;
   request.send(null);
 }
}
</script>
</head>
<body>
<progress max="100" value="0" id="prog"></progress>
<span id="percent">0</span>%
<br />
<button id="start">start</button>
<br />
<br />
<div id="disp1"></div>
<br />
<br />
<div id="disp2"></div>
</body>
</html>
```
server.py
```lang-python
import http.server
import traceback
try:
   server_address = ("", 8000)
   handler_class = http.server.CGIHTTPRequestHandler
   handler_class.cgi_directories = ["/cgi-bin"]
   server = http.server.HTTPServer(server_address, handler_class)
   server.serve_forever()
except:
   traceback.print_exc()
```
count.py
cgi-bin/count.py
```lang-python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3
from time import sleep
import traceback
import threading
import os
import main
class MainThread(threading.Thread):
   def run(self):
       main.main()
def count():
   print("Content-type: text/html;charset=utf-8\n")
   try:
       connection = sqlite3.connect("./cgi-bin/count.mdb")
       cursor = connection.cursor()
       cursor.execute("SELECT count FROM table1;")
       count = cursor.fetchall()[0][0]
       connection.commit()
       cursor.close()
   except Exception:
       traceback.print_exc()
   sleep(1)
   if count == 0:
       connection = sqlite3.connect("./cgi-bin/count.mdb")
       cursor = connection.cursor()
       cursor.execute("UPDATE table1 SET count = 1;")
       connection.commit()
       cursor.close()
       T = MainThread()
       T.start()
       #os.system("python3 ./cgi-bin/main.py")
       print(count)
       
   elif count < 10:
       print(count)
   elif count >= 10:
       print("<span>done</span>")
       
       connection = sqlite3.connect("./cgi-bin/count.mdb")
       cursor = connection.cursor()
       cursor.execute("UPDATE table1 SET count = 0;")
       connection.commit()
       cursor.close()
       
   
count()
```
main.py
cgi-bin/main.py
```lang-python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sqlite3
from time import sleep
def main():
   for i in range(10):
       connection = sqlite3.connect("./cgi-bin/count.mdb")
       cursor = connection.cursor()
       cursor.execute("SELECT count FROM table1;")
       count = cursor.fetchall()[0][0]
       cursor.execute("UPDATE table1 SET count = ?;",(count+1,))
       connection.commit()
       cursor.close()
       sleep(1)
if __name__ == "__main__":
   main()
```
回答よろしくお願いします。m(_ _)m
  • JavaScript

    35698 questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Ajax

    2139 questions

    Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

  • Python 3.x

    18171 questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る