Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Tại sao subprocess.Popen không đợi cho đến khi process con kết thúc?

subprocess.Popen , khi được khởi tạo, chạy chương trình. Tuy nhiên, nó không chờ đợi - nó kích hoạt nó ở chế độ nền như thể bạn đã nhập cmd & trong một cái vỏ. Vì vậy, trong đoạn mã trên, về cơ bản bạn đã xác định điều kiện chạy đua - nếu các phần chèn có thể kết thúc đúng lúc, nó sẽ xuất hiện bình thường, nhưng nếu không, bạn sẽ nhận được kết quả không mong muốn. Bạn không phải đợi run() đầu tiên của mình Để hoàn tất PID, bạn chỉ cần trả lại Popen của nó ví dụ và tiếp tục.

Tôi không chắc hành vi này mâu thuẫn với tài liệu như thế nào, vì có một số phương pháp rất rõ ràng trên Popen dường như chỉ ra rằng nó không được chờ đợi, như:

Popen.wait()
  Wait for child process to terminate. Set and return returncode attribute.

Tuy nhiên, tôi đồng ý rằng tài liệu cho mô-đun này có thể được cải thiện.

Để đợi chương trình kết thúc, tôi khuyên bạn nên sử dụng subprocess phương pháp tiện lợi của, subprocess.call hoặc sử dụng communicate trên Popen đối tượng (đối với trường hợp bạn cần stdout). Bạn đang thực hiện việc này cho cuộc gọi thứ hai của mình.

### START MAIN
# copy some rows from a source table to a destination table
# note that the destination table is empty when this script is run
cmd = 'mysql -u ve --skip-column-names --batch --execute="insert into destination (select * from source limit 100000)" test'
subprocess.call(cmd)

# check to see how many rows exist in the destination table
cmd = 'mysql -u ve --skip-column-names --batch --execute="select count(*) from destination" test'
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
try: count = (int(process.communicate()[0][:-1]))
except: count = 0

Ngoài ra, trong hầu hết các trường hợp, bạn không cần phải chạy lệnh trong một trình bao. Đây là một trong những trường hợp đó, nhưng bạn sẽ phải viết lại lệnh của mình giống như một chuỗi. Làm theo cách đó cũng cho phép bạn tránh bị tiêm shell truyền thống và bớt lo lắng về việc trích dẫn, như vậy:

prog = ["mysql", "-u", "ve", "--execute", 'insert into foo values ("snargle", 2)']
subprocess.call(prog)

Điều này thậm chí sẽ hoạt động và sẽ không tiêm như bạn mong đợi:

prog = ["printf", "%s", "<", "/etc/passwd"]
subprocess.call(prog)

Hãy thử nó một cách tương tác. Bạn tránh được khả năng tiêm shell, đặc biệt nếu bạn đang chấp nhận đầu vào của người dùng. Tôi nghi ngờ bạn đang sử dụng phương thức chuỗi kém tuyệt vời hơn để giao tiếp với quy trình con vì bạn đã gặp sự cố khi làm việc với các chuỗi:^)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bảng HTML động trong PHP Mail

  2. MySQL TẢI DỮ LIỆU ĐỊA PHƯƠNG INFILE Python

  3. Luồng công việc DDL giao dịch cho MySQL

  4. Thay đổi tập lệnh php thành PDO gây ra lỗi Cú pháp trong khi truy vấn cập nhật MySQL

  5. PHP 7 RC3:Cách cài đặt MySQL PDO bị thiếu