我在这里阅读了许多有关在CGI调用的脚本中启动另一个python脚本的问题的文章,即我在启用了CGI的Raspberrypi上运行了apache2服务器。
1)从浏览器:Webform数据被发送到CGI界面,并调用我的python脚本test1.py
2)来自test1.py
,我想致电test2.py
(它将永远运行或在任何需要的时间运行(它会在某处连续更新值)
3)重点是:我希望CGI脚本立即显示一些结果,例如在“结果网页”上显示“ test2已启动”并在后台运行我的test2.py
但是发生的事情是,带有表单的网页永远等待我的test2.py完成!
我尝试过类似的事情:
p = subprocess.Popen([sys.executable, '/var/www/cgi-bin/test2.py'],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
但这不起作用(即等待脚本test2完成...)
有人可以帮忙吗?
答案 0 :(得分:0)
您第一个问题的答案是此链接。getting start Cgi programmin
第二个问题的答案:您应该使用多线程编程。
如果在test2模块中具有示例功能...
create or replace procedure total_spent(v_fname IN
saleinv.cname%TYPE,v_lname IN saleinv.cname%TYPE.v_netspend OUT
saleinv.net%TYPE,v_totalpurch OUT NUMBER) AS
Begin
select sum(net+tax),count(net) into v_netspend,v_totalpurch from saleinv
where cname LIKE '&v_fname%&v_lname';
END;
/
ACCEPT p_fname PROMPT 'Enter The first letter of customer's name'
ACCEPT p_lname PROMPT 'Enter the last letter of customer's name'
BEGIN
totalspent('&p_fname',&'p_lname');
回答您的第三个问题:
然后,您可以在站点路径中的cgi文件所在的位置创建一个文件夹,或配置某些目录以将某些文件类型作为cgi脚本处理。
上面的apache2文档对此进行了很好的描述,但是实际上,要使cgi文件夹中的所有文件都执行,可以使用以下conf:
选件ExecCGI SetHandler CGI脚本
并允许将.py文件作为脚本在特定文件夹中执行,请使用以下配置文件:
#in test1.py
import threading
import test2
T1 = threading.Thread(test2.sample(object))
T1.start()
一旦有了,如果您正在运行python 3,则可以制作一个像这样的python脚本,并将其粘贴到为cgi配置的任何文件夹中:
<Directory /srv/www/yoursite/public_html>
Options +ExecCGI
AddHandler cgi-script .py
</Directory>
答案 1 :(得分:0)
谢谢,这是一个很好的答案!
我刚刚将其添加到脚本test1.py中(atm no test2.py中的任何功能只是原始代码):
[...] 导入测试2 cgitb.enable()
T1 = threading.Thread(test2) T1.start()
[...]
尽管我注意到test2确实是由线程启动的,但是网页仍然永远等待着…… 您是否有办法让网页显示某些内容而不是等待?
请注意,我也尝试过:
pid = os.fork()
#if pid==0 then we are in the child process
if(pid==0):
T1 = threading.Thread(test2)
T1.start()
#i would hope that here the child process is detached from making wait the CGI!! but no
else:
print('Content-type: text/html\n\n')
print('<h1>Python Script Test</h1>')
form = cgi.FieldStorage()
tempThVal = form['tempThresh'].value
print('Temperature threshold= ' + tempThVal)
但是仍然该死的浏览器正在等待它完成!!
答案 2 :(得分:0)
要解决此问题,您可以将自己的解决方案与我的答案结合起来以获得正确的答案。
#in test1.py
class my_thread(threading.Thread):
def __init__(self):
super().__init__()
def run(self):
p = subprocess.Popen([sys.executable, '/var/www/cgi-bin/test2.py'],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
########################
#or your test2 statment#
########################
pid = os.fork()
#if pid==0 then we are in the child process
if(pid==0):
T1 = my_thread()
T1.start()
#i would hope that here the child process is detached from making wait the CGI!! but
no
else:
print('Content-type: text/html\n\n')
print('<h1>Python Script Test</h1>')
form = cgi.FieldStorage()
tempThVal = form['tempThresh'].value
print('Temperature threshold= ' + tempThVal)
我使用此方法在Django框架中解决了此问题
答案 3 :(得分:0)
让我发布最新的代码(以防您发现某些东西)
#include <stdlib.h>
// (3) Node (of a linked list), represents a single word indexed first letter of-
// column[i] and second letter of row[i]. Think of the z axis of a table
typedef struct _node
{
char *value;
struct _node *next;
}
node;
// (2) Row, represents the second letter of a word. Think of the y axis of a table
typedef struct _row
{
node rows[26];
}
row;
// (1) Column, represents the first letter of a word. Think of the x axis of a table
typedef struct _column
{
row columns[26];
}
column;
// These are detailed below
void init_table(column *table);
void free_memory(column *table);
column hash_table;
int main(void)
{
init_table(&hash_table);
free_memory(&hash_table);
return 0;
}
// Initialize node-heads. If I don't do this, I get a 'runtime error: null-
// pointer passed as argument' when I want to access and store something in
// "node->next" or "node->value" for the first time
void init_table(column *table)
{
for (int i = 0; i < 26; i++) // For each column
{
for (int j = 0; j < 26; j++) // For each row
{
// Allocate space for a new node, as the head of a linked list.
// Max word length will be 45 letters, allocate that much space
node *first_node = malloc(sizeof(char) * 46 + sizeof(node *));
// Assign new node with value of "none", and "next" (pointer) of NULL
*first_node = (node) { .value = "none", .next = NULL };
// Store this node in the current table cell
table->columns[i].rows[j] = *first_node;
}
}
}
// Free all the memory on the heap, allocated previously
void free_memory(column *table)
{
node *ptr; // To guide the "del_node"
node *del_node; // To delete guided memory locations
for (int i = 0; i < 26; i++) // columns
{
for (int j = 0; j < 26; j++) // rows
{
// Address of the first node of the current linked list
ptr = &table->columns[i].rows[j];
while(1)
{
if(ptr->next) // If node does not point to "NULL"
{
del_node = ptr; // Guide the "del_node"
ptr = ptr->next; // Advance "ptr" to the next node
free(del_node); // Free the memory pointed by "del_node"
}
else {
break;
}
}
// Free "ptr" in case there was no next node but "ptr"
// was pointing to a node
if (ptr) free(ptr);
}
}
}