কীভাবে SIGPIPEs প্রতিরোধ করবেন (বা এগুলি সঠিকভাবে পরিচালনা করবেন)


259

আমার একটি ছোট সার্ভার প্রোগ্রাম রয়েছে যা টিসিপি বা স্থানীয় ইউনিক্স সকেটে সংযোগ গ্রহণ করে, একটি সাধারণ কমান্ড পড়ে এবং কমান্ডের উপর নির্ভর করে একটি উত্তর প্রেরণ করে। সমস্যাটি হ'ল ক্লায়েন্টের উত্তরের সাথে কখনও কখনও আগ্রহ থাকতে পারে না এবং তাড়াতাড়ি বেরিয়ে যায়, সুতরাং সেই সকেটে লেখার ফলে সাইনপাইপ হয়ে যাবে এবং আমার সার্ভার ক্র্যাশ হয়ে যাবে। এখানে দুর্ঘটনা রোধ করার সেরা অনুশীলন কোনটি? লাইনের অন্য দিকটি এখনও পড়ছে কিনা তা পরীক্ষা করার কোনও উপায় আছে? (নির্বাচন করুন) এখানে সকেটটি লেখার যোগ্য হিসাবে সর্বদা বলছে বলে মনে হয় না)। অথবা আমি কি কোনও হ্যান্ডলারের সাথে সাইনপিকে ধরতে এবং এটিকে উপেক্ষা করব?

উত্তর:


253

আপনি সাধারণত এটিকে উপেক্ষা করতে SIGPIPEএবং আপনার কোডটিতে সরাসরি ত্রুটিটি পরিচালনা করতে চান । এটি কারণ সিতে সিগন্যাল হ্যান্ডলারের তারা কী করতে পারে তার উপর অনেকগুলি বিধিনিষেধ রয়েছে।

এটি করার সর্বাধিক বহনযোগ্য উপায় SIGPIPEহ্যান্ডলারটি সেট করা SIG_IGN। এটি কোনও সকেট বা পাইপ লিখনকে SIGPIPEসংকেত তৈরি হতে আটকাবে ।

SIGPIPEসিগন্যাল উপেক্ষা করার জন্য, নিম্নলিখিত কোডটি ব্যবহার করুন:

signal(SIGPIPE, SIG_IGN);

আপনি যদি send()কলটি ব্যবহার করছেন , অন্য বিকল্পটি হ'ল বিকল্পটি ব্যবহার করা MSG_NOSIGNAL, যা SIGPIPEপ্রতি কল ভিত্তিতে আচরণটি বন্ধ করে দেবে। নোট করুন যে সমস্ত অপারেটিং সিস্টেম MSG_NOSIGNALপতাকাটিকে সমর্থন করে না ।

শেষ অবধি, আপনি SO_SIGNOPIPEসকেট পতাকাটিও বিবেচনা করতে পারেন যা setsockopt()কিছু অপারেটিং সিস্টেমের সাথে সেট করা যেতে পারে । এটি SIGPIPEকেবলমাত্র সকেটগুলিতে সেট করা আছে তাতে লেখার কারণে তা রোধ করবে ।


75
এটি সুস্পষ্ট করার জন্য: সংকেত (SIGPIPE, SIG_IGN);
jhclark

5
যদি আপনি 141 (128 + 13: SIGPIPE) এর একটি প্রস্থান রিটার্ন কোড পান তবে এটি প্রয়োজনীয় হতে পারে। SIG_IGN হ'ল উপেক্ষা সিগন্যাল হ্যান্ডলার।
ভেলক্রো

6
সকেটগুলির জন্য, এমএসজি_এনওসিআইএনএল এর সাথে প্রেরণ () ব্যবহার করা সত্যিই সহজ, যেমনটি তলাশ জানিয়েছেন।
পাভেল ভেসেলভ

3
আমার প্রোগ্রামটি একটি ভাঙ্গা পাইপে (আমার ক্ষেত্রে একটি সকেট) লিখলে ঠিক কী ঘটে? SIG_IGN প্রোগ্রামটিকে SIG_PIPE উপেক্ষা করে তোলে, কিন্তু তারপরে এর ফলে () কিছু অনাকাঙ্ক্ষিত কিছু করা যায়?
sudo

2
উল্লেখযোগ্য, যেহেতু আমি এটি একবার খুঁজে পেয়েছি, পরে এটি ভুলে গিয়ে বিভ্রান্ত হয়ে পড়েছিলাম, তারপরে এটি দ্বিতীয়বার আবিষ্কার করেছিলাম। ডিবাগার (আমি জানি জিডিবি করায়) আপনার সিগন্যাল হ্যান্ডলিংকে ওভাররাইড করে, তাই উপেক্ষিত সংকেতগুলি উপেক্ষা করা হয় না! আপনার কোডটি ডিবাগারের বাইরে পরীক্ষা করুন যাতে সাইনপাইপ আর না ঘটে তা নিশ্চিত করে। stackoverflow.com/questions/6821469/…
জেটস্কি এস-টাইপ

155

আরেকটি পদ্ধতি হ'ল সকেট পরিবর্তন করা যাতে এটি কখনই লেখার () লেখার উপর SIGPIPE তৈরি করে না। এটি লাইব্রেরিতে আরও সুবিধাজনক, যেখানে আপনি সাইনপাইপের জন্য কোনও বৈশ্বিক সংকেত হ্যান্ডলারটি নাও পেতে পারেন।

বেশিরভাগ বিএসডি-ভিত্তিক (ম্যাকস, ফ্রিবিএসডি ...) সিস্টেমগুলিতে (ধরে নিই যে আপনি সি / সি ++ ব্যবহার করছেন), আপনি এটি দিয়ে এটি করতে পারেন:

int set = 1;
setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));

এটি কার্যকরভাবে, SIGPIPE সিগন্যাল তৈরি হওয়ার পরিবর্তে, EPIPE ফিরে আসবে।


45
এটি দুর্দান্ত শোনাচ্ছে তবে SO_NOSIGPIPE লিনাক্সে উপস্থিত নেই বলে মনে হচ্ছে - সুতরাং এটি কোনও বহনযোগ্য পোর্টেবল সমাধান নয়।
nobar

1
হাই সবকিছুর, আপনি কি আমাকে বলতে পারেন যে এই কোডটি আমার কোথায় রাখবে? আমি ধন্যবাদ জানতে পারি না
আর দেবী

9
লিনাক্স, আমি পতাকা মধ্যে MSG_NOSIGNAL বিকল্প দেখতে পাঠান
Aadishri

ম্যাক ওএস এক্স
নিখুঁতভাবে কাজ করে

116

আমি পার্টিতে বেশ দেরি করে ফেলেছি, তবে SO_NOSIGPIPEপোর্টেবল নয় এবং আপনার সিস্টেমে কাজ নাও করতে পারে (এটি একটি BSD জিনিস বলে মনে হয়)।

যদি আপনি চালু থাকেন তবে একটি দুর্দান্ত বিকল্প বলুন, একটি লিনাক্স সিস্টেম ছাড়া আপনার প্রেরণে (2) কলটিতে পতাকা SO_NOSIGPIPEসেট করা হবে MSG_NOSIGNAL

write(...)দ্বারা প্রতিস্থাপন উদাহরণ send(...,MSG_NOSIGNAL)( নোবারের মন্তব্য দেখুন)

char buf[888];
//write( sockfd, buf, sizeof(buf) );
send(    sockfd, buf, sizeof(buf), MSG_NOSIGNAL );

5
অন্য কথায়, লেখার প্রতিস্থাপন হিসাবে (..., MSG_NOSIGNAL) প্রেরণটি ব্যবহার করুন () এবং আপনি সাইনপাইপ পাবেন না। এটি সকেটগুলির জন্য (সমর্থিত প্ল্যাটফর্মগুলিতে) ভালভাবে কাজ করা উচিত, তবে প্রেরণ () সকেট (পাইপ নয়) দিয়ে সীমাবদ্ধ বলে মনে হয়, তাই এটি SIGPIPE সমস্যার কোনও সাধারণ সমাধান নয়।
নোটার

@ রায় 2k পৃথিবীতে কে এখনও লিনাক্স <2.2 এর জন্য অ্যাপ্লিকেশন বিকাশ করছে? এটি আসলে একটি আধা-গুরুতর প্রশ্ন; কমপক্ষে 2.6 সহ বেশিরভাগ ডিস্ট্রোস জাহাজ
পার্থিয়ান শট

1
@ পার্থিয়ান শট: আপনার উত্তরটি পুনর্বিবেচনা করা উচিত। পুরানো এম্বেড থাকা সিস্টেমগুলি রক্ষণাবেক্ষণ করা পুরানো লিনাক্স সংস্করণগুলির যত্ন নেওয়ার একটি বৈধ কারণ।
kirsche40

1
@ kirsche40 আমি ওপি নই- আমি কেবল কৌতূহলী ছিলাম।
পার্থিয়ান শট

এই সাইটটি আমার জন্য নিখুঁতভাবে কাজ করেছে sk আমি QTcpSocketসকেটের ব্যবহার মোড়ানোর জন্য কিউটি অবজেক্টটি ব্যবহার করছি , আমাকে writeওএসের মাধ্যমে পদ্ধতি কলটি প্রতিস্থাপন করতে হয়েছিল send( socketDescriptorপদ্ধতি ব্যবহার করে )। QTcpSocketক্লাসে এই বিকল্পটি সেট করতে কোনও ক্লিনার বিকল্প জানেন ?
এমিলিও গনজলেজ মন্টাসা

29

এই পোস্টে আমি সোলারিস মামলার সম্ভাব্য সমাধান বর্ণনা করেছি যখন SO_NOSIGPIPE বা এমএসজি_এনওসিআইএনএল উপলব্ধ নয়।

পরিবর্তে, আমাদের বর্তমান থ্রেডে অস্থায়ীভাবে SIGPIPE দমন করতে হবে যা লাইব্রেরি কোডটি কার্যকর করে। এটি কীভাবে করবেন তা এখানে রয়েছে: সিগপাইপ দমন করতে আমরা প্রথমে এটি পরীক্ষা করে রাখছি কিনা তা পরীক্ষা করে দেখি। যদি এটি হয়, এর অর্থ এটি এই থ্রেডে অবরুদ্ধ। এবং আমাদের কিছুই করতে হবে না। যদি গ্রন্থাগারটি অতিরিক্ত সিপিপিইপি উত্পন্ন করে তবে এটি মুলতুবি থাকাটির সাথে একীভূত হবে এবং এটি কোনও অপশন নয়। যদি SIGPIPE মুলতুবি না থাকে তবে আমরা এটিকে এই থ্রেডে ব্লক করব এবং এটি ইতিমধ্যে অবরুদ্ধ ছিল কিনা তাও পরীক্ষা করে দেখুন। তারপরে আমরা আমাদের লেখাগুলি কার্যকর করতে মুক্ত। আমরা যখন সিপ্পিপটিকে তার আসল অবস্থায় পুনরুদ্ধার করি তখন আমরা নিম্নলিখিতটি করি: যদি SIGPIPE মূলত বিচারাধীন থাকে তবে আমরা কিছুই করি না। অন্যথায় আমরা এখন এটি মুলতুবি আছে কিনা তা পরীক্ষা করে দেখি। যদি এটি হয় (যার অর্থ হ'ল কর্মগুলি এক বা একাধিক এসআইপিআইপি তৈরি করেছে), তবে আমরা এই থ্রেডের জন্য অপেক্ষা করব, সুতরাং এর মুলতুবি স্থিতিটি সাফ করা (এটি করার জন্য আমরা সিগিটিমেডওয়েট () ব্যবহার শূন্য সময়সীমা সহ; এটি এমন একটি দৃশ্যে ব্লক করা এড়াতে হবে যেখানে দূষিত ব্যবহারকারী একটি সম্পূর্ণ প্রক্রিয়াতে ম্যানুয়ালি SIGPIPE প্রেরণ করেছিল: এক্ষেত্রে আমরা এটিকে বিচারাধীন দেখতে পাব, তবে অন্য থ্রেডটি হতে পারে এটির জন্য অপেক্ষা করার জন্য আমাদের কোনও পরিবর্তন হওয়ার আগে এটি হ্যান্ডেল করুন)। মুলতুবি স্থিতি সাফ করার পরে আমরা এই থ্রেডে SIGPIPE অবরোধ মুক্ত করি, তবে কেবলমাত্র এটি প্রাথমিকভাবে অবরুদ্ধ না হলে।

Https://github.com/kroki/XProbes/blob/1447f3d93b6dbf273919af15e59f35cca58fcc23/src/libxprobes.c#L156 এ কোড কোড উদাহরণ


22

স্থানীয়ভাবে SIGPIPE পরিচালনা করুন

গ্লোবাল সিগন্যাল ইভেন্ট হ্যান্ডলারের পরিবর্তে স্থানীয়ভাবে ত্রুটিটি হ্যান্ডেল করা ভাল কারণ স্থানীয়ভাবে আপনার কী চলছে এবং কী গ্রহণ করা উচিত সে সম্পর্কে আপনার আরও প্রসঙ্গ থাকবে।

আমার অ্যাপ্লিকেশনগুলির একটিতে আমার একটি যোগাযোগ স্তর রয়েছে যা আমার অ্যাপ্লিকেশনটিকে একটি বাহ্যিক আনুষঙ্গিক সাথে যোগাযোগ করতে দেয়। যখন কোনও লেখার ত্রুটি দেখা দেয় আমি যোগাযোগ স্তরটিতে নিক্ষেপ করি এবং ব্যতিক্রম করি এবং এটি হ্যান্ডেল করার জন্য এটি চেষ্টা করে ব্লক পর্যন্ত বুদবুদ করে দিন।

কোড:

একটি সিগপাইপ সিগন্যাল উপেক্ষা করার কোডটি যাতে আপনি স্থানীয়ভাবে এটি পরিচালনা করতে পারেন:

// We expect write failures to occur but we want to handle them where 
// the error occurs rather than in a SIGPIPE handler.
signal(SIGPIPE, SIG_IGN);

এই কোডটি SIGPIPE সিগন্যালটিকে বাড়াতে বাধা দেবে, তবে সকেটটি ব্যবহার করার চেষ্টা করার সময় আপনি একটি পড়ার / লেখার ত্রুটি পাবেন, সুতরাং আপনাকে এটি পরীক্ষা করে দেখতে হবে।


এই কলটি কোনও সকেটের সাথে সংযুক্ত হওয়ার পরে বা তার আগে করা উচিত? কোথায় রাখা ভাল? ধন্যবাদ
আহমেদ

@Ahmed আমি ব্যক্তিগতভাবে এটা করা applicationDidFinishLaunching: । প্রধান জিনিসটি এটি সকেট সংযোগের সাথে আলাপচারিতার আগে হওয়া উচিত।
স্যাম

তবে সকেটটি ব্যবহার করার চেষ্টা করার সময় আপনি একটি পঠন / লেখার ত্রুটি পাবেন, সুতরাং আপনার এটি পরীক্ষা করা দরকার। - আমি কীভাবে এটি সম্ভব? সিগন্যাল (SIGPIPE, SIG_IGN) আমার জন্য কাজ করে তবে ডিবাগ মোডের অধীনে এটি একটি ত্রুটি ফেরায় কি সেই ত্রুটিটিকেও উপেক্ষা করা সম্ভব?
jongbanaag

@ ড্রেফিউস 15 আমি বিশ্বাস করি যে স্থানীয়ভাবে হ্যান্ডেল করার জন্য আমি সকেটকে চেষ্টা / ক্যাপ ব্লক দিয়ে স্রেফ গুটিয়ে রেখেছি। আমি এটি দেখে কিছুক্ষণ হয়ে গেল।
স্যাম

15

আপনি পাইপের একদম প্রান্তে প্রক্রিয়াটি প্রস্থান করা থেকে আটকাতে পারবেন না এবং আপনি লেখার কাজ শেষ করার আগে যদি এটি উপস্থিত হয় তবে আপনি একটি সিপাইপ সিগন্যাল পাবেন। আপনি যদি সিগন্যালটি SIG_IGN করেন তবে আপনার লেখাটি একটি ত্রুটির সাথে ফিরে আসবে - এবং আপনাকে সেই ত্রুটিটি লক্ষ্য করে প্রতিক্রিয়া জানাতে হবে। কোনও হ্যান্ডলারের মধ্যে কেবল সিগন্যাল ধরা এবং উপেক্ষা করা ভাল ধারণা নয় - আপনার অবশ্যই নোটটি অবশ্যই নষ্ট হয়ে যাবে এবং প্রোগ্রামটির আচরণটি পরিবর্তন করবে যাতে এটি আবার পাইপে লিখবে না (কারণ সংকেতটি আবার উত্পন্ন হবে, এবং উপেক্ষা করা হবে) আবার, এবং আপনি আবার চেষ্টা করুন, এবং পুরো প্রক্রিয়াটি দীর্ঘ সময়ের জন্য চলতে পারে এবং প্রচুর সিপিইউ শক্তি নষ্ট করতে পারে)।


6

অথবা আমি কি কোনও হ্যান্ডলারের সাথে সাইনপিকে ধরতে এবং এটিকে উপেক্ষা করব?

আমি বিশ্বাস করি যে ঠিক আছে। আপনি জানতে চাইছেন কখন অন্য প্রান্তটি তাদের বর্ণনাকারী বন্ধ করে দিয়েছে এবং এটিই আপনাকে সাইনপাইপ বলে।

স্যাম


3

লিনাক্স ম্যানুয়াল বলেছেন:

EPIPE স্থানীয় প্রান্তটি সংযোগ ভিত্তিক সকেটে বন্ধ করা হয়েছে। এক্ষেত্রে MSG_NOSIGNAL সেট না করা পর্যন্ত প্রক্রিয়াটি একটি SIGPIPEও পাবে।

তবে উবুন্টু 12.04 এর জন্য এটি ঠিক নয়। আমি এই মামলার জন্য একটি পরীক্ষা লিখেছি এবং আমি সর্বদা ইপাইপ উইথ এসআইপিআইপি পাই। আমি দ্বিতীয় বার একই ভাঙ্গা সকেটে লেখার চেষ্টা করলে সাইনপাইপ উত্পন্ন হয়। সুতরাং আপনার যদি সিগন্যালটি ঘটে তবে এটি আপনার প্রোগ্রামে যুক্তিযুক্ত ত্রুটি বোঝায় SIGPIPE উপেক্ষা করার দরকার নেই।


1
লিনাক্সের সকেটে ইপিআইপিই না দেখে আমি অবশ্যই স্পষ্টভাবে এসআইপিআইপিই পাই। এটি কার্নেল বাগের মতো শোনাচ্ছে।
ডেভম্যাক

3

এখানে দুর্ঘটনা রোধ করার সেরা অনুশীলন কোনটি?

হয় প্রতিটি হিসাবে sigpines অক্ষম করুন, বা ত্রুটি ধরা এবং উপেক্ষা।

লাইনের অন্য দিকটি এখনও পড়ছে কিনা তা পরীক্ষা করার কোনও উপায় আছে?

হ্যাঁ, নির্বাচন করুন () ব্যবহার করুন।

নির্বাচন () এখানে কাজ করবে বলে মনে হয় না কারণ এটি সর্বদা বলে যে সকেটটি লিখনযোগ্য।

আপনার পড়ার বিটগুলিতে নির্বাচন করতে হবে । আপনি সম্ভবত উপেক্ষা করতে পারেন লেখার বিট ।

যখন প্রান্তটি তার ফাইল হ্যান্ডেলটি বন্ধ করে দেয়, তখন নির্বাচন আপনাকে জানাবে যে পড়ার জন্য ডেটা প্রস্তুত রয়েছে। আপনি যখন যান এবং এটি পড়েন, আপনি 0 বাইট ফিরে পাবেন, যা ওএস আপনাকে বলবে যে ফাইল হ্যান্ডেলটি বন্ধ হয়ে গেছে।

কেবলমাত্র আপনি যখন লেখার বিটগুলি উপেক্ষা করতে পারবেন না তা হ'ল আপনি যদি বড় পরিমাণে পাঠাচ্ছেন এবং অন্য প্রান্তটি ব্যাকলগ হওয়ার ঝুঁকি রয়েছে যা আপনার বাফারগুলি পূরণ করতে পারে। যদি এটি ঘটে থাকে তবে ফাইল হ্যান্ডেলটিতে লেখার চেষ্টা করার ফলে আপনার প্রোগ্রাম / থ্রেডটি ব্লক বা ব্যর্থ হতে পারে। লেখার আগে বাছাইয়ের পরীক্ষা আপনাকে এ থেকে রক্ষা করবে, তবে এটির গ্যারান্টি নেই যে অন্য প্রান্তটি স্বাস্থ্যকর বা আপনার ডেটা আসতে চলেছে।

নোট করুন যে আপনি কাছাকাছি থেকে সিগপাইপ পেতে পারেন () পাশাপাশি আপনি যখন লিখবেন।

বন্ধ করুন কোনও বাফার ডেটা ফ্লাশ করে। যদি অন্য প্রান্তটি ইতিমধ্যে বন্ধ হয়ে গেছে, তবে বন্ধটি ব্যর্থ হবে এবং আপনি একটি সিগপাইপ পাবেন।

আপনি যদি বাফার টিসিপিআইপি ব্যবহার করে থাকেন তবে একটি সফল লেখার অর্থ হল আপনার ডেটা প্রেরণের জন্য সারিবদ্ধ করা হয়েছে, এর অর্থ এই নয় যে এটি প্রেরণ করা হয়েছে। যতক্ষণ না আপনি সফলভাবে কাছে কল করবেন, আপনি জানেন না যে আপনার ডেটা প্রেরণ করা হয়েছে।

সিগপাইপ আপনাকে বলছে যে কিছু ভুল হয়েছে, এটি আপনাকে কী করবে না বা আপনার কী করা উচিত তা আপনাকে জানায় না।


সিগপাইপ আপনাকে বলছে যে কিছু ভুল হয়েছে, এটি আপনাকে কী করবে না বা আপনার কী করা উচিত তা আপনাকে জানায় না। যথাযথভাবে। কার্যত সিগপাইপের একমাত্র উদ্দেশ্য হ'ল পাইপযুক্ত কমান্ড লাইন ইউটিলিটিগুলি ছিন্ন করা যখন পরবর্তী পর্যায়ে আর ইনপুটটির প্রয়োজন হয় না। যদি আপনার প্রোগ্রামটি নেটওয়ার্কিং করছে, আপনার সাধারণত ব্লক করা উচিত বা SIGPIPE প্রোগ্রাম-ব্যাপী অগ্রাহ্য করা উচিত।
হতাশাডানিয়েল

অবিকল। সাইনপাইপ "XXX টি শিরোনাম | সন্ধান করুন" এর মতো পরিস্থিতির জন্য is মাথা একবার তার 10 টি লাইন মিলে গেলে, সন্ধানটি চালিয়ে যাওয়ার কোনও লাভ নেই। সুতরাং মাথাটি বাইরে বেরিয়ে আসে এবং পরের বার এটির সাথে কথা বলার চেষ্টা করে এটি সিগপাইপ পায় এবং জানে যে এটিও প্রস্থান করতে পারে।
বেন অ্যাভেলিং

সত্যই, SIGPIPE এর একমাত্র উদ্দেশ্য হ'ল প্রোগ্রামগুলিকে ম্লান হতে দেওয়া এবং লেখায় ত্রুটি অনুসন্ধান করা না করা!
উইলিয়াম পার্সেল

2

একটি আধুনিক পসিক্স সিস্টেমের অধীনে (যেমন লিনাক্স), আপনি sigprocmask()ফাংশনটি ব্যবহার করতে পারেন ।

#include <signal.h>

void block_signal(int signal_to_block /* i.e. SIGPIPE */ )
{
    sigset_t set;
    sigset_t old_state;

    // get the current state
    //
    sigprocmask(SIG_BLOCK, NULL, &old_state);

    // add signal_to_block to that existing state
    //
    set = old_state;
    sigaddset(&set, signal_to_block);

    // block that signal also
    //
    sigprocmask(SIG_BLOCK, &set, NULL);

    // ... deal with old_state if required ...
}

আপনি যদি পূর্বের অবস্থাটি পরে পুনরুদ্ধার করতে চান তবে old_stateকোথাও নিরাপদ সংরক্ষণ নিশ্চিত করুন । যদি আপনি সেই ফাংশনটিকে একাধিকবার কল করেন তবে আপনাকে স্ট্যাক ব্যবহার করতে হবে বা কেবল প্রথম বা শেষ সংরক্ষণ করতে হবে old_state... অথবা কোনও ফাংশন থাকতে পারে যা নির্দিষ্ট ব্লক করা সংকেতটিকে সরিয়ে দেয়।

আরও তথ্যের জন্য ম্যান পৃষ্ঠাটি পড়ুন


এটির মতো ব্লকড সিগন্যালের সেটটি পঠন-সংশোধন / লেখার প্রয়োজন নেই। sigprocmaskঅবরুদ্ধ সিগন্যালের সেটটিতে যোগ করে, তাই আপনি একক কল দিয়ে এই সমস্ত করতে পারেন।
লুচস

আমি পঠন-সংশোধন-লেখা করি না , আমি বর্তমান অবস্থা যা সংরক্ষণ করি তা সংরক্ষণ করতে আমি পড়ি old_stateযাতে আমি যদি পছন্দ করি তবে পরে এটিকে পুনরুদ্ধার করতে পারি। আপনি যদি জানেন যে আপনাকে আর রাজ্য পুনরুদ্ধার করতে হবে না, সত্যিই এইভাবে এটি পড়তে এবং সংরক্ষণ করার দরকার নেই।
অ্যালেক্সিস উইলক

1
তবে আপনি কি করেন: sigprocmask()পুরানো অবস্থা পড়ার জন্য প্রথম কল , sigaddsetএটির পরিবর্তনের জন্য কল, এটি কল করার জন্য দ্বিতীয় কল sigprocmask()। আপনি প্রথম কলটি সরিয়ে ফেলতে, আরম্ভ করতে sigemptyset(&set)এবং দ্বিতীয় কলটিতে পরিবর্তন করতে পারেন sigprocmask(SIG_BLOCK, &set, &old_state)
লুচস

আহ! হা হা! তুমি ঠিক বলছো. আমি করি. ভাল ... আমার সফ্টওয়্যারটিতে, আমি জানি না যে আমি ইতিমধ্যে কোন সংকেতগুলি অবরুদ্ধ করেছি বা অবরুদ্ধ করেছি। সুতরাং আমি এটি এইভাবে না। তবে আমি সম্মত হই যে আপনার যদি কেবল একটি "সেট সংকেত এইভাবে" থাকে তবে একটি সাধারণ পরিষ্কার + সেট যথেষ্ট।
অ্যালেক্সিস উইলকে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.