2012-03-07 37 views
24

Trên hộp Linux của tôi, sig_atomic_t là một đồng bằng cũ int. Do ints có chất lượng nguyên tử đặc biệt không?Linux: Tại sao sig_atomic_t typedef'ed thành int?

$ gcc -v 
Using built-in specs. 
Target: x86_64-linux-gnu 
... 
Thread model: posix 
gcc version 4.3.2 (Debian 4.3.2-1.1) 

$ echo '#include <signal.h>' | gcc -E - | grep atomic 
typedef int __sig_atomic_t; 
typedef __sig_atomic_t sig_atomic_t; 
+0

@chrisaycock: C? Điều này sẽ không áp dụng bất kỳ ngôn ngữ nào có quyền truy cập vào biến 'sig_atomic_t' không? Tôi có thể dễ dàng sử dụng 'g ++'. – smcdow

+4

Loại 'sig_atomic_t' thực sự là một phần của đặc điểm kỹ thuật C. Nó cũng được tìm thấy trong đặc tả C++ (như hầu hết mọi thứ), nhưng bạn có nhiều khả năng nhận được câu trả lời hay nhất với thẻ C. –

+2

C không đảm bảo điều đó. CPU cụ thể có đảm bảo cụ thể cho nguyên tử của một số loại nhất định. Đặc biệt, các CPU hiện đại được sử dụng trong các hệ thống máy tính để bàn có xu hướng đảm bảo nguyên tử ít nhất là đối với 'int' được liên kết (tức là dữ liệu có kích thước từ nền tảng). Đây không phải là trường hợp điển hình cho các CPU cũ hơn, hoặc cho các CPU được sử dụng trong các hệ thống nhúng. – ninjalj

Trả lời

33

C99 sig_atomic_t phù hợp duy nhất một định nghĩa rất yếu "nguyên tử", bởi vì C99 không có khái niệm đồng thời, chỉ interruptibility. (C2011 thêm một mô hình đồng thời, và cùng với nó là _Atomic loại mà đưa ra đảm bảo mạnh hơn, tuy nhiên, AFAIK sig_atomic_t là không thay đổi, vì nó raison d'être vẫn là giao tiếp với bộ xử lý tín hiệu, chứ không phải trên chủ đề.)

này là tất cả mọi thứ C99 nói về sig_atomic_t:

(§7.14 <signal.h>, đoạn 2) các loại định nghĩa là sig_atomic_t, đó là (có thể không ổn định đủ tiêu chuẩn) kiểu số nguyên của một đối tượng có thể được truy cập như một thực thể nguyên tử, ngay cả khi có sự gián đoạn không đồng bộ. (§7.14 <signal.h>, đoạn 2)

(§7.14p5) Nếu [a] tín hiệu xảy ra khác hơn là kết quả của cách gọi abort hoặc raise chức năng, hành vi là undefined nếu xử lý tín hiệu dùng để chỉ bất kỳ đối tượng với tĩnh thời gian lưu trữ khác với việc gán giá trị cho một đối tượng được khai báo là volatile sig_atomic_t.

(§7.18.3 Giới hạn của các loại nguyên khác, khoản 3) Nếu sig_atomic_t (xem 7.14) được định nghĩa là một loại nguyên ký, giá trị của SIG_ATOMIC_MIN sẽ không lớn hơn -127 và giá trị của SIG_ATOMIC_MAX chịu không ít hơn 127; cách khác, sig_atomic_t được định nghĩa là một kiểu dữ liệu integer unsigned, và giá trị của SIG_ATOMIC_MIN sẽ là 0 và giá trị của SIG_ATOMIC_MAX không được nhỏ hơn 255.

Thuật ngữ "thực thể nguyên tử" không được định nghĩa bất cứ nơi nào trong tiêu chuẩn . Dịch từ tiêu chuẩn-ese, các ý định là CPU hoàn toàn có thể cập nhật một biến loại sig_atomic_t trong bộ nhớ ("thời gian lưu trữ tĩnh") với một hướng dẫn máy. Do đó, trong máy đồng trừu tượng C99 không gián đoạn, chính xác, không thể xử lý được, một bộ xử lý tín hiệu không thể quan sát biến số sig_atomic_tnửa chừng thông qua bản cập nhật. §7.18.Giấy phép ngôn ngữ 3p3 loại này nhỏ đến char nếu cần. Lưu ý vui lòng hoàn thành hoàn thành vắng mặt của bất kỳ ngôn ngữ nào liên quan đến tính nhất quán của bộ xử lý chéo.

Có các CPU thực yêu cầu nhiều lệnh để viết giá trị lớn hơn char vào bộ nhớ. Ngoài ra còn có các CPU thực đòi hỏi nhiều hơn một lệnh để viết các giá trị nhỏ hơn một từ máy (thường, nhưng không nhất thiết, giống như int) vào bộ nhớ. Ngôn ngữ trong hướng dẫn sử dụng GNU C Library hiện không chính xác. Nó đại diện cho một mong muốn trên một phần của các tác giả ban đầu để loại bỏ những gì họ thấy là giấy phép không cần thiết cho việc triển khai C để làm những điều kỳ lạ làm cho cuộc sống khó khăn hơn cho các lập trình viên ứng dụng. Thật không may, đó là giấy phép rất là những gì làm cho nó có thể có C ở tất cả trên một số máy thực sự. Có ít nhất một cổng Linux nhúng (với AVR) mà không phải int cũng không có thể ghi vào bộ nhớ trong một lệnh. (Mọi người đang nỗ lực làm cho hướng dẫn chính xác hơn, xem ví dụ: http://sourceware.org/ml/libc-alpha/2012-02/msg00651.html - sig_atomic_t dường như đã bị bỏ qua trong đó.)

+1

Có glibc có một cổng AVR? – ninjalj

+1

Heh, có vẻ như không. Nó có lẽ sẽ tốt hơn với một cái gì đó nhỏ hơn :) Tôi có xu hướng suy nghĩ, rằng Linux/AVR với bất kỳ thư viện C có nhiều khả năng là một mục tiêu di động có liên quan hiện nay hơn Hurd hoặc các hệ điều hành khác nhưng không được nhúng. – zwol

+0

Ok, sau đó tôi sẽ giả sử hướng dẫn sử dụng glibc không chính xác. (Lưu ý rằng nó nói: _In practice_ và _these là true trên tất cả các máy mà thư viện GNU C hỗ trợ_) – ninjalj

7

Một số loại nhất định có thể yêu cầu nhiều hướng dẫn để đọc/ghi. int loại luôn được đọc/ghi nguyên tử.

Data Type: sig_atomic_t

Đây là một loại nguyên liệu. Các đối tượng thuộc loại này luôn được truy cập một cách nguyên tử.

Trong thực tế, bạn có thể giả định rằng các loại số nguyên int và khác không còn là so với int là nguyên tử. Bạn cũng có thể giả định rằng các loại con trỏ là nguyên tử; đó là rất thuận tiện. Cả hai điều này đều đúng trên tất cả các máy mà thư viện GNU C hỗ trợ và trên tất cả các hệ thống POSIX, chúng tôi biết.

Reference

+8

Đó là * thường là * trường hợp 'int' luôn được đọc và viết một cách nguyên tử. Tiêu chuẩn C không bảo đảm điều này. Việc thực hiện, bằng cách định nghĩa 'sig_atomic_t' là' int', hứa rằng trường hợp * cho việc triển khai thực hiện *. Bạn không nên cho rằng đó là sự thật cho tất cả các triển khai. –

+0

Một [tham chiếu] hiện tại (http://www.gnu.org/software/libc/manual/html_mono/libc.html#Atomic-Data-Access). Chỉ cần làm rõ, điều này chỉ áp dụng cho thư viện GNU C? Có hoặc không có GCC? Tôi đã không bao giờ nghe nói về một loại đơn giản có truy cập nguyên tử trong tiêu chuẩn C (không bao gồm các phương pháp nguyên tử bình thường và cơ chế khóa). – Ioan

+0

@Ianan C99 không có mô hình đồng thời, vì vậy ý ​​nghĩa của "nguyên tử" là cái gì đó rất yếu so với những gì bạn có thể nghĩ đến. Xem câu trả lời của tôi. – zwol

Các vấn đề liên quan