पहले चेतावनी: मैं यहां जिज्ञासा से बाहर हैकिंग कर रहा हूं। मेरे पास नीचे क्या कर रहा है करने के लिए मेरे पास कोई विशिष्ट कारण नहीं है!पायथन
नीचे MacOS 10.12.5
मैं चारों ओर अजगर के साथ हैकिंग था पर Python 2.7.13
पर किया जाता है और मैंने सोचा कि यह देखने के लिए कि मैं
fcntl.fcntl(sys.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
nonblocking fcntl
करने के लिए कॉल है stdout
बनाया क्या हुआ दिलचस्प होगा निश्चित रूप से सफल मैं फिर बड़ी मात्रा में डेटा लिखने की कोशिश करता हूं (ओएसएक्स पर एक पाइप के अधिकतम बफर आकार से बड़ा - जो 65536 बाइट्स है)। मैं इसे विभिन्न तरीकों से करता हूं और अलग-अलग परिणाम प्राप्त करता हूं, कभी-कभी अपवाद करता हूं, कभी-कभी जो असफल लगता है।
प्रकरण 1
fcntl.fcntl(sys.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
try:
sys.stdout.write("A" * 65537)
except Exception as e:
time.sleep(1)
print "Caught: {}".format(e)
# Safety sleep to prevent quick exit
time.sleep(1)
यह हमेशा अपवाद Caught: [Errno 35] Resource temporarily unavailable
फेंकता है। मुझे लगता है कि समझ में आता है। उच्च स्तरीय फ़ाइल ऑब्जेक्ट रैपर मुझे बता रहा है कि लिखने की कॉल विफल रही है।
प्रकरण 2
fcntl.fcntl(sys.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
try:
sys.stdout.write("A" * 65537)
except Exception as e:
print "Caught: {}".format(e)
# Safety sleep to prevent quick exit
time.sleep(1)
यह कभी कभी अपवाद फेंकता Caught: [Errno 35] Resource temporarily unavailable
या कभी कभी भी इसका अपवाद नहीं पकड़ा है और मैं निम्नलिखित उत्पादन देखें:
close failed in file object destructor:
sys.excepthook is missing
lost sys.stderr
प्रकरण 3
fcntl.fcntl(sys.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
try:
sys.stdout.write("A" * 65537)
except Exception as e:
print "Caught: {}".format(e)
# Safety sleep to prevent quick exit
time.sleep(1)
print "Slept"
यह कभी-कभी अपवाद Caught: [Errno 35] Resource temporarily unavailable
फेंकता है या कभी-कभी कोई अपवाद नहीं पकड़ा जाता है और मुझे बस "स्लीप्ट" दिखाई देता है। ऐसा लगता है कि print
आईएनजी द्वारा "सो" मैं प्रकरण 2. से
प्रकरण 4
fcntl.fcntl(sys.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
try:
os.write(sys.stdout.fileno(), "A" * 65537)
except Exception as e:
print "Caught: {}".format(e)
# Safety sleep to prevent quick exit
time.sleep(1)
हमेशा ठीक त्रुटि संदेश नहीं मिलता है!
प्रकरण 5
fcntl.fcntl(sys.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
try:
print os.write(sys.stdout.fileno(), "A" * 65537)
except Exception as e:
print "Caught: {}".format(e)
# Safety sleep to prevent quick exit
time.sleep(1)
यह कभी कभी ठीक है या कभी कभी close failed in file object destructor
त्रुटि संदेश प्रिंट करता है।
मेरा सवाल यह है कि यह इस तरह पाइथन में क्यों विफल हो जाता है? क्या मैं यहाँ कुछ मौलिक रूप से बुरा कर रहा हूं - या तो पाइथन या सिस्टम स्तर पर?
ऐसा लगता है कि लिखने से पहले ही लिखना बहुत जल्द लिख रहा है जब लेखन पहले से विफल हुआ है त्रुटि संदेश का कारण बनता है। त्रुटि अपवाद नहीं प्रतीत होती है। कोई विचार नहीं है कि यह कहां से आ रहा है।
एनबी।मैं सी में समकक्ष प्रोग्राम लिख सकता हूं और यह ठीक काम करता है:
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <sys/fcntl.h>
#include <unistd.h>
int main(int argc, const char * argv[])
{
const size_t NUM_CHARS = 65537;
char buf[NUM_CHARS];
// Set stdout non-blocking
fcntl(fileno(stdout), F_SETFL, O_NONBLOCK);
// Try to write a large amount of data
memset(buf, 65, NUM_CHARS);
size_t written = fwrite(buf, 1, NUM_CHARS, stdout);
// Wait briefly to give stdout a chance to be read from
usleep(1000);
// This will be written correctly
sprintf(buf, "\nI wrote %zd bytes\n", written);
fwrite(buf, 1, strlen(buf), stdout);
return 0;
}
मुझे लगता है कि * * समस्या यह है कि गैर-अवरुद्ध आईओ के साथ, 'os.write' को कॉल करने से पहले लिखना है लौट सकते है पूरा करें, और चूंकि यह आपके सरल परीक्षण कार्यक्रम को समाप्त करता है, इसलिए लिखने से पहले 'sys.stdout' भी बंद किया जा सकता है। ध्यान दें कि आपका सी प्रोग्राम इंतजार कर रहा है ('नींद (1000) ') जहां आपका पायथन कोड नहीं है। प्रतिक्रिया के लिए – chepner
धन्यवाद। मुझे पायथन कोड का एक और पूर्ण स्निपेट पोस्ट करना चाहिए था। मेरे पास लिखने के बाद 'time.sleep (1) 'था और इससे कोई फर्क नहीं पड़ता :( –
आपका ओएस क्या है? आप पाइथन को' स्ट्रेस 'जैसी चीज़ों के तहत चलाने का प्रयास कर सकते हैं और देख सकते हैं कि सिस्टम कॉल किस प्रकार की जाती है। –