2009-05-12 19 views
5

Và làm cách nào để tìm hiểu xem có bất kỳ lỗi nào trong số đó xảy ra hay không và dẫn đến lỗi được trả về bởi fork() hoặc system()? Nói cách khác, nếu fork() hoặc system() trả về lỗi, một số thứ trong Linux mà tôi có thể kiểm tra để chẩn đoán tại sao lỗi cụ thể đó lại xảy ra là gì?Một số điều kiện nào có thể khiến các cuộc gọi fork() hoặc system() thất bại trên Linux?

Ví dụ:

  • Chỉ cần đơn giản ra khỏi bộ nhớ (kết quả trong errno ENOMEM) - kiểm tra sử dụng bộ nhớ với 'miễn phí' vv
  • nhớ Không đủ cho kernel để sao chép bảng trang và thông tin kế toán khác của quá trình cha mẹ (kết quả trong errno EAGAIN)
  • Có giới hạn quy trình toàn cầu không? (kết quả trong errno EAGAIN cũng?)
  • Có giới hạn quy trình cho mỗi người dùng không? Làm thế nào tôi có thể tìm ra nó là gì?
  • ...?
+0

Để làm rõ, khi người ta biết rằng một lỗi như EAGAIN đã xảy ra trong fork() (errno == EAGAIN), làm thế nào để bạn tìm ra nguyên nhân gây ra nó (RLIMIT_NPROC?) trang bảng, hoặc cấu trúc nhiệm vụ, và nếu như vậy tại sao?Và làm thế nào để bạn tránh nó?) –

+0

Tôi cũng đã hỏi một câu hỏi khác, nhưng liên quan đến các bảng trang trong Linux: http://stackoverflow.com/questions/853736/how-to-find-or-calculate-a-linux- processs-page-table-size-và-other-kernel-accou –

Trả lời

6

Và làm cách nào để tìm hiểu xem có bất kỳ sự kiện nào trong số đó xảy ra không?

Kiểm tra errno giá trị nếu kết quả (trở về giá trị) là -1

Từ trang người đàn ông trên Linux:

RETURN GIÁ TRỊ
Mở thành công, PID của quá trình con được trả về trong phụ huynh, và 0 được trả về trong đứa trẻ. Trên thất bại, -1 được trả về trong phụ huynh, không có tiến trình con nào được tạo ra, và errno được thiết lập một cách thích hợp.

LỖI
EAGAIN
fork() không thể bố trí đủ bộ nhớ để sao chép bảng trang của phụ huynh và phân bổ một cấu trúc nhiệm vụ cho đứa trẻ.
EAGAIN
Không thể tạo quy trình mới vì giới hạn tài nguyên RLIMIT_NPROC của người gọi đã gặp phải. Để vượt quá giới hạn này, quy trình phải có CAP_SYS_ADMIN hoặc khả năng CAP_SYS_RESOURCE.
ENOMEM
fork() không thể phân bổ cấu trúc hạt nhân cần thiết vì bộ nhớ bị chặt.

XÁC ĐỊNH ĐẾN SVr4, 4.3BSD, POSIX.1-2001.

+1

Giá trị trả về là -1, biến errno được đặt thành EAGAIN, ENOMEM, v.v. –

+0

@Chas. Owens Đó là những gì tôi nói. "Kiểm tra giá trị errno NẾU kết quả là -1". – lothar

+0

Ah, tôi phân tích cú pháp nó như kiểm tra errno cho -1, xin lỗi. –

1

nproc trong /etc/security/limits.conf có thể giới hạn số lượng quy trình cho mỗi người dùng.

Bạn có thể kiểm tra lỗi bằng cách kiểm tra lợi tức từ ngã ba. Một 0 có nghĩa là bạn đang ở trong đứa trẻ, một số dương là pid của đứa trẻ và có nghĩa là bạn đang ở trong phụ huynh, và một số âm có nghĩa là ngã ba thất bại. Khi ngã ba thất bại nó đặt biến bên ngoài errno. Bạn có thể sử dụng các hàm trong errno.h để kiểm tra nó. Tôi thường chỉ sử dụng perror để in lỗi (với một số văn bản được thêm vào nó) để stderr.

#include <stdio.h> 
#include <errno.h> 
#include <unistd.h> 

int main(int argc, char** argv) { 
    pid_t pid; 

    pid = fork(); 
    if (pid == -1) { 
     perror("Could not fork: "); 
     return 1; 
    } else if (pid == 0) { 
     printf("in child\n"); 
     return 0; 
    }; 

    printf("in parent, child is %d\n", pid); 

    return 0; 
} 
Các vấn đề liên quan