Có thể $! gây ra điều kiện chủng tộc khi được sử dụng trong các kịch bản chạy song song?


8

Giả sử tôi có nhiều tập lệnh bash chạy song song, với mã như sau:

#!/bin/bash

tail -f /dev/null &
echo "pid is "$!

Được $!đảm bảo để cung cấp cho tôi PID của tác vụ nền gần đây nhất trong tập lệnh đó hay nó là tác vụ nền gần đây nhất trên toàn cầu? Tôi chỉ tò mò liệu việc dựa vào tính năng này có thể gây ra tình trạng chủng tộc khi PID mà nó trả về là từ một quá trình bắt đầu trong một tập lệnh khác.

Câu trả lời:


16

$!được đảm bảo cung cấp cho bạn pid của quá trình trong đó shell thực thi taillệnh đó . Shell là một luồng đơn, mỗi shell sống trong tiến trình riêng của nó với tập hợp các biến riêng. Không có cách nào $!một vỏ sẽ rò rỉ vào một vỏ khác, giống như việc gán biến vỏ trong một vỏ sẽ không ảnh hưởng đến biến cùng tên trong vỏ khác (nếu chúng ta đặt các biến phổ biến của fishvỏ) .

Bây giờ, tail -f /dev/nulllà một lệnh chạy vô thời hạn, nhưng đối với các lệnh có thời gian tồn tại ngắn, lưu ý rằng vì có một số lượng hạn chế các id quy trình có thể, nên các id quá trình chắc chắn sẽ được sử dụng lại.

Trong:

true &
pid=$!

$pidsẽ chứa id của tiến trình mà shell chạy true, nhưng khi bạn sử dụng nó $pid, pid đó có thể đã chết và có thể đề cập đến một quy trình khác.


3
Đúng, tôi đã biết về điểm thứ hai của bạn và rằng nếu bạn muốn tạo một trình quản lý quy trình nền đáng tin cậy, bạn cần sử dụng ngôn ngữ đảm bảo bạn sẽ biết chính xác thời điểm khi một tiến trình con đã thoát và PID của nó đã được đưa trở lại nhóm , mà rõ ràng các kịch bản shell không thể vì chúng gặt hái các tiến trình con một cách mạnh mẽ. Cảm ơn bạn đã giải thích rõ ràng.
philraj

5
@philraj, trong zsh, bạn có thể cài đặt trình xử lý trên SIGCHLD được xử lý khi chấm dứt các công việc không đồng bộ và sử dụng $jobstate/$jobtextđể kiểm tra trạng thái quy trình tại đó. Không phải không có chủng tộc vì đứa trẻ đã được gặt vào thời điểm bẫy được thực thi, nhưng điều đó có nghĩa là các cửa sổ cuộc đua rất ngắn trong đó các pids rất khó có thể được sử dụng lại.
Stéphane Chazelas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.