質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

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

Python

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

Ajax

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

Q&A

解決済

1回答

4311閲覧

python3 http.serverにおけるThreading

namnium1125

総合スコア2043

Python 3.x

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

Python

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

Ajax

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

0グッド

0クリップ

投稿2017/09/08 16:12

編集2017/09/08 16:18

お世話になります。

以前質問しましたことを解決する為にいろいろ取り組んでいたのですが、また壁に当たってしまい、もう一度、少し内容を変えて質問させていただきます。ご了承ください。

前回の質問に書いた通り、時間のかかる処理の経過をプログレスバーを表示したいです。

その為に調べているとはてなの方に解決方法っぽいことが書いてありましたので、その通りに取り組んでいました。

ただDjangoに取り組んだことがなく、またすでにhttp.serverのほうでプログラムを組んでしまっていたため(個人使用なのでサーバーとしては十分です。)、cron、celeryではなくデータベースを利用する方法を考えました。

最終的には画像のようにすればいいのかなと思いました。

イメージ説明

しかし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

1<!doctype html> 2<html> 3<head> 4<meta charset="utf-8"> 5<title>Progress By Ajax</title> 6<script> 7var request = new XMLHttpRequest(); 8var progress; 9var percent; 10var disp1; 11var disp2; 12var start; 13 14var url = "/cgi-bin/count.py"; 15 16var rT = 0; 17 18if(request){ 19 window.addEventListener("load",function(e){ 20 progress = document.getElementById("prog"); 21 //↓最終的にはこっちで出力したい 22 percent = document.getElementById("percent"); 23 start = document.getElementById("start"); 24 //↓とりあえずこっちに出力 25 disp1 = document.getElementById("disp1"); 26 disp2 = document.getElementById("disp2"); 27 28 start.addEventListener("click",function(e){ 29 30 request.open("GET",url,true); 31 request.onreadystatechange = sub; 32 request.send(null); 33 },false); 34 },false); 35} 36 37function sub(){ 38 disp1.innerHTML = "readyState : " + request.readyState + "<br />status : " + request.status; 39 rT = request.responseText!="" ? request.responseText : rT; 40 disp2.innerHTML = rT; 41 42 console.log("requestText : " + rT); 43 var i = rT.isNaN ? 10 : parseInt(rT); 44 if(i<10&&request.readyState==4){ 45 request.open("GET",url,true); 46 request.onreadystatechange = sub; 47 request.send(null); 48 } 49} 50</script> 51</head> 52<body> 53<progress max="100" value="0" id="prog"></progress> 54<span id="percent">0</span>% 55<br /> 56<button id="start">start</button> 57<br /> 58<br /> 59<div id="disp1"></div> 60<br /> 61<br /> 62<div id="disp2"></div> 63</body> 64</html>

server.py

lang

1import http.server 2import traceback 3 4try: 5 server_address = ("", 8000) 6 handler_class = http.server.CGIHTTPRequestHandler 7 handler_class.cgi_directories = ["/cgi-bin"] 8 server = http.server.HTTPServer(server_address, handler_class) 9 server.serve_forever() 10except: 11 traceback.print_exc()

cgi-bin/count.py

lang

1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4import sqlite3 5from time import sleep 6import traceback 7 8import threading 9import os 10import main 11 12class MainThread(threading.Thread): 13 def run(self): 14 main.main() 15 16def count(): 17 print("Content-type: text/html;charset=utf-8\n") 18 try: 19 connection = sqlite3.connect("./cgi-bin/count.mdb") 20 cursor = connection.cursor() 21 22 cursor.execute("SELECT count FROM table1;") 23 count = cursor.fetchall()[0][0] 24 25 connection.commit() 26 cursor.close() 27 except Exception: 28 traceback.print_exc() 29 30 sleep(1) 31 32 if count == 0: 33 connection = sqlite3.connect("./cgi-bin/count.mdb") 34 cursor = connection.cursor() 35 cursor.execute("UPDATE table1 SET count = 1;") 36 connection.commit() 37 cursor.close() 38 39 T = MainThread() 40 T.start() 41 #os.system("python3 ./cgi-bin/main.py") 42 43 print(count) 44 45 elif count < 10: 46 print(count) 47 elif count >= 10: 48 print("<span>done</span>") 49 50 connection = sqlite3.connect("./cgi-bin/count.mdb") 51 cursor = connection.cursor() 52 cursor.execute("UPDATE table1 SET count = 0;") 53 connection.commit() 54 cursor.close() 55 56 57count()

cgi-bin/main.py

lang

1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4import sqlite3 5from time import sleep 6 7def main(): 8 for i in range(10): 9 connection = sqlite3.connect("./cgi-bin/count.mdb") 10 cursor = connection.cursor() 11 12 cursor.execute("SELECT count FROM table1;") 13 count = cursor.fetchall()[0][0] 14 15 cursor.execute("UPDATE table1 SET count = ?;",(count+1,)) 16 17 connection.commit() 18 cursor.close() 19 20 sleep(1) 21 22if __name__ == "__main__": 23 main()

回答よろしくお願いします。m(_ _)m

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

基本的には提示された流れでよいと思います。
subprocess.Popenを使うことでmain.pyの終了を待たずに起動できますのでスレッドは不要です。
subprocess.Popen('python3 ./cgi-bin/main.py')

sqlite詳しくないですが、main.py側でのDBコネクションはループ外側で1回open/closeでよいと思います。
また、自分ならcount.pyで行っている処理開始時のレコードcount=0セット処理はmain.py側に持ってきます。
すなわちmain.py側だけがcount値を更新しcount.py側はcount値を見るだけとします。

投稿2017/09/10 06:39

can110

総合スコア38266

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

namnium1125

2017/09/12 01:03

subprocess.Popen("./cgi-bin/main.py')でうまく行きました! また仰った通りopen/closeは1回でよかったみたいです! 回答ありがとうございました。m(_ _)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問