Tôi đã thực hiện một chương trình C khá đơn giản để tính toán các điều khoản của chuỗi Fibonacci, mà tôi đang chạy trên Ubuntu. Tôi đã tạo ra một số cấu trúc dữ liệu khá vụng về để nó có thể làm các số nguyên rất lớn, nhưng các chi tiết cụ thể của chương trình không quan trọng lắm - điều quan trọng là chương trình có thể mất nhiều thời gian để thực hiện các tính toán.Chạy chương trình C với nhiều luồng trong nền khi nó yêu cầu đầu vào của người dùng
Vì tò mò, tôi quyết định làm cho chương trình bắt đầu tính toán và sau đó cho phép người dùng nhập một ký tự để xem cách tính toán bao xa. Vì vậy, trong trường hợp này, nếu chương trình đang tính toán thuật ngữ thứ n của dãy Fibonacci và nó chưa được thực hiện, thì nhập số '1' sẽ nhận được chương trình xuất kết quả k mà nó hiện đang tính toán. Tôi đã cố gắng làm điều đó bằng cách sử dụng cách tiếp cận sau.
Chương trình sử dụng scanf để nhận số nguyên dài đại diện cho thuật ngữ của chuỗi cần được tính toán. Chương trình sau đó tạo một luồng với thường trình mà tôi đã viết để tính toán và in thuật ngữ Fibonacci n'th, thoát ra khi nó đã hoàn thành việc đó. Sau đó, chương trình tạo ra một biến số nguyên i được sử dụng để lưu trữ đầu vào và khởi tạo nó để một số giá trị khác 0. Sau đó nó liên tục đi vào một vòng lặp while, miễn là int đó khác 0, và trong mỗi lần lặp của vòng lặp nó thực hiện một scanf ("% d", & i). Sau đó nó so sánh giá trị đó với 1 và nếu đó là 1 thì nó sẽ in giá trị của bộ đếm mà tôi đã thiết lập để theo dõi tiến trình tính toán Fibonacci.
Dù sao, tất cả các công việc trên đều rất trơn tru mặc dù tôi đang quá sâu sắc với những thứ như chủ đề. Tuy nhiên, vấn đề mà tôi đang gặp phải là khi tôi phải tính toán, thuật ngữ thứ triệu của chuỗi chương trình mất vài phút để hoàn thành, và sẽ thật tuyệt nếu chỉ chạy nó trong nền. Tuy nhiên, nếu tôi đặt quá trình trong nền với ctrl + z và sau đó gõ bg, quá trình bắt đầu nhưng ngay lập tức dừng lại. Tôi đoán rằng điều này là bởi vì nó liên tục đòi hỏi đầu vào từ người dùng và do đó nó dừng lại cho đến khi nó nhận được đầu vào đó.
Bất kỳ đề xuất nào về cách phá vỡ vấn đề trên sẽ được đánh giá cao. Tôi không đặc biệt lo lắng về vấn đề cụ thể này (tính toán các số Fibonacci) vì đó chỉ là một vấn đề khá ngẫu nhiên mà tôi đã chọn để sử dụng cho việc tính toán. Tôi quan tâm hơn đến vấn đề chung của việc tạo ra một cách cơ bản để người dùng nhập các lệnh vào chương trình, chương trình sẽ thực hiện trong các luồng riêng biệt, nhưng vẫn cho phép người dùng chạy chương trình trong nền nếu cần.
Xin lỗi cho câu hỏi khá dài và cảm ơn trước sự giúp đỡ của bạn!
Phil
Chỉnh sửa: Theo yêu cầu, tôi đã thêm (một phiên bản rất đơn giản) mã ở đây. Ý tưởng cơ bản là giống nhau: chương trình khởi chạy tính toán dài trong một chuỗi mới, sau đó lặp lại các đầu vào bằng scanf. Nhập 0 quits chương trình, nhập 1 sẽ hiển thị một bộ đếm cho biết tiến trình tính toán. Tôi muốn để có thể chạy chương trình trong nền, nhưng vì nó liên tục yêu cầu đầu vào nó dừng quá trình ngay lập tức. Bỏ qua tràn số học trên bộ đếm; chương trình thực tế của tôi có cấu trúc dữ liệu để xử lý loại nội dung này nhưng tôi đã cố gắng đơn giản hóa mã của mình càng nhiều càng tốt để có thể đọc được.
//Simple program to test threading and input.
#include <stdio.h>
#include <pthread.h>
#define NUM_THREADS 2
void *stuff();
int counter; //keeps track of the progress of the computation
int main(){
counter=1;
pthread_t threads[NUM_THREADS];
pthread_create(&threads[0], NULL, stuff, NULL);
//loop while the input is non-zero so that the program can
//accept commands
int input=10;
while(input){
input=10;
printf("Enter 0 to exit or 1 to display progress: ");
scanf("%d", &input);
if(input==1){
printf("Currently iterating for the %dth time.\n", counter);
}
}
return 0;
}
//Randomly chosen computation that takes a while.
void *stuff(){
long i,j,n=1000000000;
for(i=0; i<=n; i++){
for(j=0; j<=n; j++){
i*i*i*i*i*i*i*i*i*i*i;
j*j*j*j*j*j*j*j*j*j*j;
counter++;
}
}
printf("Done.\n");
pthread_exit(NULL);
}
Thay vì mô tả dài dòng, bạn có thể xem xét đăng mã của mình :-) –
Điểm được chụp! Hy vọng rằng điều này làm rõ mọi thứ lên một chút. – ptmx
Tôi khuyên bạn nên sử dụng trình xử lý tín hiệu thay vì nhập bằng 'scanf' ... Sau đó,' kill -SIGUSR1 <ứng dụng của bạn pid> 'có thể được sử dụng để kích hoạt báo cáo của bạn ngay cả khi ứng dụng được tạo nền. – JimR