Sau khi mở đường ống đến một quy trình với popen
, có cách nào để giết quá trình đã được bắt đầu không? (Sử dụng pclose
không phải là những gì tôi muốn bởi vì điều đó sẽ chờ cho quá trình kết thúc, nhưng tôi cần phải giết nó.)giết một quá trình bắt đầu bằng popen
Trả lời
Không sử dụng popen() và viết trình bao bọc của riêng bạn làm những gì bạn muốn.
Nó khá đơn giản để fork(), và sau đó thay thế stdin & stdout bằng cách sử dụng dup2(), và sau đó gọi exec() trên con bạn.
Bằng cách đó, cha mẹ của bạn sẽ có con PID chính xác và bạn có thể sử dụng kill() trên đó.
Tìm kiếm Google để thực hiện "popen2()" đối với một số mã mẫu trên cách triển khai popen() đang làm gì. Nó chỉ dài hơn một chục dòng hoặc dài . Lấy từ dzone.com chúng ta có thể thấy một ví dụ trông như thế này:
#define READ 0
#define WRITE 1
pid_t
popen2(const char *command, int *infp, int *outfp)
{
int p_stdin[2], p_stdout[2];
pid_t pid;
if (pipe(p_stdin) != 0 || pipe(p_stdout) != 0)
return -1;
pid = fork();
if (pid < 0)
return pid;
else if (pid == 0)
{
close(p_stdin[WRITE]);
dup2(p_stdin[READ], READ);
close(p_stdout[READ]);
dup2(p_stdout[WRITE], WRITE);
execl("/bin/sh", "sh", "-c", command, NULL);
perror("execl");
exit(1);
}
if (infp == NULL)
close(p_stdin[WRITE]);
else
*infp = p_stdin[WRITE];
if (outfp == NULL)
close(p_stdout[READ]);
else
*outfp = p_stdout[READ];
return pid;
}
NB: Có vẻ như popen2() là những gì bạn muốn, nhưng phân bố của tôi dường như không đi kèm với phương pháp này.
Cách rõ ràng là hệ thống ("pkill process_name");
Rõ ràng đây là vấn đề nếu bạn có nhiều trường hợp của quy trình đang chạy.
Trường hợp này xảy ra khi nhiều phiên bản đang chạy và cần phải nhắm mục tiêu một phiên bản chính xác. – jldupont
popen không thực sự bắt đầu một chuỗi, mà là loại bỏ một quy trình. Khi tôi nhìn vào định nghĩa, nó không giống như có một cách dễ dàng để có được PID của quá trình đó và giết nó. Có thể có những cách khó khăn như kiểm tra quá trình cây, nhưng tôi đoán bạn nên được tốt hơn với việc sử dụng đường ống, ngã ba và chức năng exec để bắt chước hành vi của popen. Sau đó, bạn có thể sử dụng PID bạn nhận được từ ngã ba() để giết quá trình con.
Trên thực tế nếu quá trình này được thực hiện I/O (mà nó phải được, nếu không tại sao popen
thay vì system
(3)?), Sau đó pclose
nên Whack nó với một SIGPIPE
lần sau nó sẽ cố gắng để đọc hoặc viết, và nó sẽ rơi trên độc đáo :-)
Tôi đã làm một cái gì đó tương tự trong python, nơi bạn có thể giết chết một tiến trình con và bất kỳ quy trình con được chia nhỏ cho điều đó. Nó tương tự như giải pháp của slacy thực sự. http://www.pixelbeat.org/libs/subProcess.py
Đây là phiên bản cải tiến của popen2 (tín dụng là do Sergey L.). Phiên bản được đăng bởi slacy không trả về PID của quá trình được tạo trong popen2, nhưng PID được gán cho sh
.
pid_t popen2(const char **command, int *infp, int *outfp)
{
int p_stdin[2], p_stdout[2];
pid_t pid;
if (pipe(p_stdin) != 0 || pipe(p_stdout) != 0)
return -1;
pid = fork();
if (pid < 0)
return pid;
else if (pid == 0)
{
close(p_stdin[WRITE]);
dup2(p_stdin[READ], READ);
close(p_stdout[READ]);
dup2(p_stdout[WRITE], WRITE);
execvp(*command, command);
perror("execvp");
exit(1);
}
if (infp == NULL)
close(p_stdin[WRITE]);
else
*infp = p_stdin[WRITE];
if (outfp == NULL)
close(p_stdout[READ]);
else
*outfp = p_stdout[READ];
return pid;
}
Phiên bản mới sẽ được gọi với
char *command[] = {"program", "arg1", "arg2", ..., NULL};
Tôi không thấy bất kỳ sự khác biệt trong phần pid; bạn có thể cập nhật nhận xét về phần khác biệt không. – nayab
Cảm ơn cờ vua cho phiên bản của bạn, thực sự tốt! –
Tôi có theo ý tưởng của @slacy tạo ra chức năng popen2.
Nhưng tìm thấy vấn đề khi quá trình con là chết, quá trình cha mẹ vẫn đọc tập tin descripter outfp
không trở về từ chức năng.
Điều đó có thể khắc phục bằng cách thêm ống không sử dụng gần vào quy trình gốc.
close(p_stdin[READ]);
close(p_stdout[WRITE]);
Chúng tôi có thể nhận đúng pid của quy trình mới bằng cách sử dụng bash làm shell.
execl("/bin/bash", "bash", "-c", command, NULL);
Khi quá trình đứa trẻ chết người gọi chức năng popen2
nên thu thập trạng thái của quá trình trẻ em bằng cách gọi pclose2
. nếu chúng ta không thu thập quy trình con trạng thái đó có thể là quá trình zombie khi nó chấm dứt.
Đây là mã đầy đủ đã kiểm tra và hoạt động như mong đợi.
#define READ 0
#define WRITE 1
pid_t
popen2(const char *command, int *infp, int *outfp)
{
int p_stdin[2], p_stdout[2];
pid_t pid;
if (pipe(p_stdin) != 0 || pipe(p_stdout) != 0)
return -1;
pid = fork();
if (pid < 0)
return pid;
else if (pid == 0)
{
dup2(p_stdin[READ], STDIN_FILENO);
dup2(p_stdout[WRITE], STDOUT_FILENO);
//close unuse descriptors on child process.
close(p_stdin[READ]);
close(p_stdin[WRITE]);
close(p_stdout[READ]);
close(p_stdout[WRITE]);
//can change to any exec* function family.
execl("/bin/bash", "bash", "-c", command, NULL);
perror("execl");
exit(1);
}
// close unused descriptors on parent process.
close(p_stdin[READ]);
close(p_stdout[WRITE]);
if (infp == NULL)
close(p_stdin[WRITE]);
else
*infp = p_stdin[WRITE];
if (outfp == NULL)
close(p_stdout[READ]);
else
*outfp = p_stdout[READ];
return pid;
}
int
pclose2(pid_t pid) {
int internal_stat;
waitpid(pid, &internal_stat, 0);
return WEXITSTATUS(internal_stat);
}
tôi chỉ đơn giản đưa vào (bash) kịch bản, trong dòng đầu tiên:
echo PID $$
sau đó tôi đọc pid, và sử dụng nó để làm một: kill (pid, 9)
popen là cheesy để bắt đầu, đây là một giải pháp cheesy tốt đẹp cho vấn đề cheesy. – stu
- 1. Quá trình giết chết được mở bằng popen()?
- 2. Giám sát không bắt đầu quá trình bị giết
- 3. Hệ điều hành bắt đầu quá trình giết khi quá trình python đa luồng chạy
- 4. Giết một quá trình và chờ quá trình thoát
- 5. Giết một quá trình python
- 6. Mở một quá trình với Popen và nhận được PID
- 7. Bắt đầu một quá trình riêng biệt
- 8. giết subprocess khi quá trình python bị giết?
- 9. bắt đầu quá trình ghi trong Groovy
- 10. Giết một quá trình thông qua sshj
- 11. onStartCommand sau khi quá trình dịch vụ bị giết khi bắt đầu với START_STICKY
- 12. Bắt đầu quá trình phi cao từ quá trình cao
- 13. Quá trình bắt đầu và mạo danh
- 14. Làm thế nào để giết một quá trình nohup?
- 15. Quá trình giết trong Shell Script
- 16. Quá trình bắt đầu từ luồng
- 17. Hủy quá trình bắt đầu qua System.Diagnostics.Process.Start()
- 18. Quá trình đồng bộ C# bắt đầu
- 19. Monit không bắt đầu quá trình
- 20. Bắt đầu quá trình trong Java?
- 21. Làm cách nào để tìm ID quá trình (pid) của quá trình được bắt đầu bằng java?
- 22. Quá trình bị giết bởi SIGKILL
- 23. Có thể cho một quá trình java trong một jvm để giết/dừng một quá trình java khác trong jvm?
- 24. giết tất cả child_process khi quá trình nút bị giết
- 25. Làm thế nào để giết một quá trình từ WiX
- 26. Lưu gmon.out trước khi giết một quá trình
- 27. Hadoop: Quá trình Datanode bị giết
- 28. Giết chết một quá trình tạo ra với subprocess.Popen Python()
- 29. là có một cách để bắt đầu/ngừng các quá trình linux với python?
- 30. soạn cập nhật "quá trình giết"
điều này không giải quyết được vấn đề trùng lặp bộ nhớ của ngã ba. có thể là chúng tôi không muốn gọi đến ngã ba vì lý do này – Will
@phooji python phải làm gì với bất kỳ thứ gì? –
@ MahmoudAl-Qudsi: Rất tiếc. Tôi chắc đã loooking quá nhiều câu hỏi python. [Nhận xét liên quan đến python trước đó đã được chỉnh sửa] – phooji