Tôi đang phát triển một ứng dụng sử dụng C++ và biên dịch bằng cách sử dụng Linux GNU C Compiler. Tuy nhiên, tôi muốn gọi một hàm khi người dùng ngắt tập lệnh bằng cách sử dụng các phím CtrlC. Tôi nên làm gì? Mọi câu trả lời sẽ được đánh giá cao.Ctrl + C ngắt sự kiện xử lý trong Linux
Trả lời
Khi bạn bấm Ctr + C, hệ điều hành sẽ gửi một signal để quá trình này . Có nhiều tín hiệu và một trong số đó là SIGINT. SIGINT ("ngắt chương trình") là một trong các Tín hiệu Chấm dứt.
Có một vài loại Tín hiệu chấm dứt khác, nhưng điều thú vị về SIGINT là chương trình của bạn có thể xử lý (bị bắt). Hành động mặc định của SIGINT là chấm dứt chương trình. Tức là, nếu chương trình của bạn không xử lý tín hiệu này một cách cụ thể, khi bạn nhấn Ctr + C thì chương trình của bạn sẽ chấm dứt làm tác vụ mặc định.
Để thay đổi hành động mặc định của tín hiệu, bạn phải đăng ký tín hiệu bị bắt. Để đăng ký một tín hiệu trong một chương trình C (ít nhất là dưới hệ thống POSIX) có hai chức năng
- signal(int signum, sighandler_t handler);
- sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);.
Các chức năng này yêu cầu tiêu đề signal.h để được bao gồm trong mã C của bạn. Tôi cung cấp một ví dụ đơn giản về chức năng signal
bên dưới với các nhận xét.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h> // our new library
volatile sig_atomic_t flag = 0;
void my_function(int sig){ // can be called asynchronously
flag = 1; // set flag
}
int main(){
// Register signals
signal(SIGINT, my_function);
// ^ ^
// Which-Signal |-- which user defined function registered
while(1)
if(flag){ // my action when signal set it 1
printf("\n Signal caught!\n");
printf("\n default action it not termination!\n");
flag = 0;
}
return 0;
}
Lưu ý: bạn chỉ nên gọi safe/authorized functions trong bộ xử lý tín hiệu. Ví dụ: avoid calling printf in signal handler.
Bạn có thể biên dịch mã này bằng gcc và thực thi nó từ trình bao. Có một vòng lặp vô hạn trong mã và mã sẽ chạy cho đến khi bạn gửi tín hiệu SIGINT
bằng cách nhấn Ctr + C.
Bạn có thể để lại bình luận cho bạn nghi ngờ, tôi chỉ cố gắng cung cấp cho bạn một điểm khởi đầu nhanh chóng. Tôi tin rằng với một số nỗ lực nhiều hơn, bạn sẽ khám phá những điều chi tiết. –
Cảm ơn bạn đã trả lời và trả lời của bạn, điều đó hoạt động rất tốt. – mozcelikors
Tôi khá chắc chắn quá trình này được gửi một tín hiệu, không phải là một đơn. :-) – celtschk
Nhập CtrlC thường khiến vỏ gửi SIGINT
vào chương trình của bạn. Thêm trình xử lý cho tín hiệu đó (qua số signal(2)
hoặc sigaction(2)
) và bạn có thể làm những gì bạn thích khi nhấn CtrlC.
Cách khác, nếu bạn chỉ quan tâm đến việc dọn dẹp trước khi thoát khỏi chương trình, hãy thiết lập trình xử lý thoát qua atexit(3)
có thể phù hợp hơn.
Bạn có thể sử dụng macro tín hiệu.
Dưới đây là một ví dụ về cách đối phó với nó: sản lượng
#include <signal.h>
#include <stdio.h>
void sigint(int a)
{
printf("^C caught\n");
}
int main()
{
signal(SIGINT, sigint);
for (;;) {}
}
mẫu:
Ethans-MacBook-Pro:~ phyrrus9$ ./a.out
^C^C caught
^C^C caught
^C^C caught
^C^C caught
^C^C caught
tránh sử dụng printf trong bộ xử lý tín hiệu –
Đơn giản như vậy. Tôi sử dụng nó để đóng kết nối i2c để printf sẽ được thay thế bằng chức năng giết kết nối. Cảm ơn thực sự. – mozcelikors
Bạn cần [Xác định trình xử lý tín hiệu] (http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_21.html#SEC351) cho SIGINT, lấy ý tưởng từ [this code] (http: // stackoverflow.com/questions/17705842/is-there-a-way-to-make-my-chương trình-làm việc-với-ít-code) –
Làm thế nào để làm việc này với trình biên dịch được sử dụng? –
@mozcelikors Không có những thứ như "thư viện được công nhận bởi GCC". Nếu có một thư viện được viết bằng tiêu chuẩn C, bất kỳ trình biên dịch C lành mạnh nào cũng có thể biên dịch nó. –