2012-11-19 30 views
14

Tôi muốn tạo bản sao của quy trình bằng cách sử dụng ngã ba() trong C. Tôi không biết cách chuyển đối số cho các bản sao của quy trình của mình. Ví dụ, tôi muốn chuyển một số nguyên cho các bản sao quy trình.Làm thế nào để chuyển đối số cho các quá trình được tạo bởi fork()

Hoặc tôi phải làm gì, nếu tôi có một vòng lặp trong đó tôi gọi fork() và muốn vượt qua một giá trị duy nhất để các quá trình (ví dụ 0 ... N)

for (int i = 0; i < 4; ++i) { 
    fork(); 
    // pass a unique value to new processes. 
} 
+2

'fork' tạo bản sao của quy trình đang diễn ra, quá trình này không * khởi tạo * một quy trình. – Beta

+0

Đọc http://advancedlinuxprogramming.com/ –

Trả lời

15

Phần tốt đẹp về fork() là mỗi quá trình bạn đẻ trứng tự động nhận được một bản sao của tất cả những gì mẹ có, ví dụ như vậy, giả sử chúng ta muốn vượt qua một int myvar cho mỗi hai quá trình đứa trẻ nhưng tôi muốn mỗi để có một giá trị khác nhau từ quá trình cha mẹ:

int main() 
{ 
    int myvar = 0; 
    if(fork()) 
     myvar = 1; 
    else if(fork()) 
     myvar = 2; 
    else 
     myvar = 3; 

    printf("I'm %d: myvar is %d\n", getpid(), myvar); 
    return 0; 
} 

Vì vậy, làm điều này cho phép mỗi tiến trình để có một "bản sao" của myvar với giá trị riêng của nó.

I'm 8517: myvar is 1 
I'm 8518: myvar is 2 
I'm 8521: myvar is 3 

Nếu bạn không thay đổi giá trị, thì mỗi quá trình xử lý sẽ có cùng giá trị.

+0

cảm ơn mike. bạn đánh vào đầu –

1

Xem exec() family của chức năng.

CHỈNH SỬA: Nếu bạn đang cố gắng khởi tạo các bản sao của cùng một chương trình với quy trình cơ sở, chỉ cần tiếp tục sử dụng các biến theo đề xuất của duskwuff.

1

Bạn có thể sử dụng sao chép() (thực tế được sử dụng bởi ngã ba()). Nó cho phép bạn vượt qua arg vào chức năng nhập của bạn.

http://linux.die.net/man/2/clone

+3

Không, vui lòng không. 'clone' là một phức tạp, Linux cụ thể, syscall đòi hỏi một kiến ​​thức rất tốt về Linux, và chủ yếu được dành riêng cho vài thư viện * thực hiện * thread (à la pthread). Xem thêm trang 'futex (7)'. –

+0

@BasileStarynkevitch: Chính xác. Chỉ sử dụng bản sao nếu bạn đang thực hiện một số hack cấp thấp thực sự - điểm duy nhất của bản sao là cho phép bạn làm một số thứ trong không gian người dùng mà trước đây chỉ có thể xảy ra trong không gian hạt nhân, chẳng hạn như thực hiện luồng. Nó không phải là một syscall sử dụng chung. – Linuxios

7

biến địa phương và toàn cầu vốn đã được bảo tồn qua một fork(), do đó không cần phải "vượt qua đối số". Nếu bạn đang gọi một chức năng trong quá trình chia hai, bạn có thể làm điều gì đó như:

pid_t pid = fork(); 
if (pid == 0) { 
    funcToCallInChild(argument); 
    exit(0); 
} 
6

tôi đến trễ để trả lời, nhưng đây là cách tôi làm điều đó:

const char *progname = "./yourProgName"; 
const char *argument1 = "arg1"; 
const char *argument2 = "arg2"; 

if (fork() == 0) 
{ 
    // We are the child process, so replace the process with a new executable. 
    execl(progname, progname, argument1, argument2, (char *)NULL); 
} 
// The parent process continues from here. 

Trước tiên, bạn fork() quá trình này để tạo ra một quy trình mới. Nó vẫn có cùng một không gian bộ nhớ như cũ. fork() trả về cho cả quá trình cha và con. Nếu fork() trả về 0, bạn là tiến trình con. Quá trình con sau đó sử dụng execl() để thay thế bộ nhớ tiến trình bằng một từ một tệp mới.

Lưu ý rằng progname được cấp hai lần cho execl(). Đầu tiên là những gì execl() thực sự sẽ cố gắng chạy, thứ hai là argv [0]. Bạn phải cung cấp cả hai hoặc đếm đối số sẽ bị tắt bởi một. Progname phải chứa tất cả thông tin đường dẫn cần thiết để tìm hình ảnh thực thi mong muốn.

Tôi đưa ra hai đối số trong ví dụ này, nhưng bạn có thể chuyển bao nhiêu tùy ý. nó phải được chấm dứt bằng NULL, và tôi nghĩ rằng bạn phải cast nó như là (char *) như tôi hiển thị.

Cách tiếp cận này cung cấp cho bạn quy trình hoàn toàn độc lập với các đối số và một pid duy nhất. Nó có thể tiếp tục chạy lâu sau khi quá trình cha mẹ chấm dứt, hoặc nó có thể chấm dứt trước khi cha mẹ.

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