ห้องสมุดแบบคงที่ C ขมวดคิ้วอยู่หรือไม่? [ปิด]


11

มี 2 ​​อาร์กิวเมนต์สำหรับการมีไลบรารีที่แบ่งใช้:

  1. ช่วยลดพื้นที่ดิสก์
  2. เมื่อมีการอัปเดตไลบรารีที่ใช้ร่วมกันไบนารีทั้งหมดขึ้นอยู่กับว่าจะได้รับการอัปเดต

มีข้อเสียเปรียบหนึ่งสำหรับไลบรารีที่แชร์:

  • พวกเขา (สามารถ) แนะนำนรกพึ่งพา

บนคอมพิวเตอร์เดสก์ท็อปข้อได้เปรียบอันดับหนึ่งไม่ได้ถืออีกต่อไปแล้ว การสูญเสียพื้นที่ดิสก์ไม่เป็นปัญหามากในทุกวันนี้

การมีไบนารีแบบคงที่จะช่วยให้เราจัดการผู้จัดการแพคเกจได้ดีขึ้น - ฉันหมายถึงนรกที่พึ่งพาได้จะเป็นอดีต การเพิ่มโปรแกรมจะเป็นการเพิ่มไบนารี ในที่สุดโฟลเดอร์ที่ให้มันจัดการกับไฟล์ การลบโปรแกรมจะเป็นการลบไฟล์นี้ พึ่งพา? ที่ไปแล้ว.

ข้อได้เปรียบที่สองยังคงมีอยู่ แต่ฉันคิดว่าข้อดีของไบนารีคงที่ในคอมพิวเตอร์เดสก์ท็อปนั้นมีน้ำหนักมากกว่า ฉันหมายถึงแม้แต่ภาษาใหม่อย่าง Go ก็รวบรวมไบนารีทั้งหมดของพวกเขาทั้งๆที่มีข้อได้เปรียบของ shared library เพราะความสะดวก


เนื่องจากข้อได้เปรียบหลักอย่างหนึ่งของไลบรารีที่ใช้ร่วมกันไม่ใช่เรื่องใหญ่อีกต่อไปแล้ว C นิ่งไลบรารียังคงขมวดคิ้วอยู่หรือไม่? ถ้าเป็นเช่นนั้นทำไม


4
สาเหตุหลักที่ C ใช้งานอีกต่อไปนั้นเป็นเรื่องเฉพาะเพราะคุณไม่ได้ทำงานกับคอมพิวเตอร์ตั้งโต๊ะที่ทันสมัย
Telastyn

18
@Telastyn ฉันขอโทษ? ซอฟต์แวร์ส่วนใหญ่ที่ติดตั้งในคอมพิวเตอร์เดสก์ท็อปของฉันเขียนใน C.
Florian Margaine

6
บิตด้านข้าง - เว็บไซต์ที่อ่านนอกเรื่อง - การเชื่อมโยงแบบไดนามิกถือว่าเป็นอันตราย

6
ข้อดีอย่างหนึ่งของไลบรารีแบบไดนามิกคือผู้คนยังคงสามารถอัปเดตไลบรารีเพื่อแก้ไขข้อบกพร่องรูโหว่ด้านความปลอดภัยหรือปัญหาฮาร์ดแวร์ในเกมโอเพ่นซอร์สอายุ 15 ปีของคุณที่หยุดรับอัปเดตมานาน เป็นกรณีเฉพาะ แต่เนื่องจากเกมที่ดีไม่ใช่สินค้า "แค่ใช้โปรแกรมอื่น" ก็ไม่ได้ช่วยอะไร มันเป็นเรื่องสำคัญสำหรับการปฏิบัติตาม LGPL โดยไม่ต้องเปิดรหัสของคุณ
Doval

4
คุณลืมข้อดีอีกสองข้อของไลบรารี่ที่แชร์: 1) พวกมันแชร์ในหน่วยความจำด้วย 2) ลิงเกอร์ทั้งหมดดูดแย่มาก การแยกไบนารีออกเป็นเอนทิตีขนาดเล็กหลาย ๆ อันทำให้กระบวนการทั้งหมดมีความทนทานมากขึ้น
SK-logic

คำตอบ:


9

หลักฐานของคำถามของคุณมีข้อบกพร่อง สิ่งที่ขมวดคิ้วคือการยึดมั่นในหลักคำสอนและสัมบูรณ์โดยไม่เข้าใจพื้นฐานเบื้องหลังการเขียนโปรแกรม (Cargo ลัทธิ?)

คำตอบ SO ที่เชื่อมโยงคือการศึกษาที่น่าสนใจในหัวข้อนั้นมาก - คำถามนั้นเกี่ยวกับสาเหตุที่คอมไพล์กับ - ตัวเลือกแบบสแตติกไม่ทำงานคำตอบที่คุณเชื่อมโยงกับไม่มีอะไรมากไปกว่าคำโม้เรื่องการเชื่อมโยงแบบคงที่ หากไม่ได้พูดถึงสาเหตุที่ไม่ดีและต้องการให้ OP ใช้การเชื่อมโยงแบบไดนามิก มันโชคร้ายที่มันถูกทำเครื่องหมายว่าเป็นคำตอบที่ถูกต้อง (คำตอบต่อไปนี้มีคะแนนเสียงมากกว่าสองเท่าและเป็นคำตอบที่ถูกต้องสำหรับคำถามของ OP) เพราะถึงแม้ว่าคำตอบที่ถูกต้องจะอยู่ที่นั่น

คำถามจริงคืออะไรข้อดีข้อเสียของการเชื่อมโยงแบบคงที่และแบบไดนามิกและเมื่อหนึ่งจะเป็นที่ต้องการมากกว่าที่อื่น


2
คำตอบของ Basile จะบอกคุณอย่างแม่นยำว่าเหตุใดเขาจึงแนะนำให้ใช้ไลบรารีที่แบ่งใช้: "ทำไมคุณต้องการเชื่อมโยงแอปพลิเคชันของคุณแบบสแตติก? นี่เป็นข้อผิดพลาด (เพราะคุณไม่ได้กำไรจากการอัปเดตไปยังไลบรารีไดนามิกของระบบ) สิ่งอำนวยความสะดวกจาก libc ต้องการไลบรารีแบบไดนามิก "ไม่ใช่" คำโหยหา "เพียงเพราะคุณไม่เห็นด้วย
โคดี้เกรย์

@Cody คำตอบที่เชื่อมโยงไปยังได้รับการแก้ไขตั้งแต่ฉันเรียกมันว่าคุยโว ความคิดเห็นเดียวที่ฉันยึดไว้กับการเชื่อมโยงแบบคงที่ vs แบบไดนามิกคือการใช้สิ่งที่เหมาะสมกับความต้องการของคุณและเข้าใจจุดแข็งและจุดอ่อนของตัวเลือกแทนที่จะตกอยู่ในลัทธิการเขียนโปรแกรมลัทธิขนส่งสินค้าเพราะ "มีคนพูดเช่นนั้น"
mattnz

ใช่มีการเพิ่มส่วน "โดยเฉพาะอย่างยิ่ง ... " ไม่แน่ใจว่ามันมีผลต่อสถานะพูดจาโผงผาง แน่นอนฉันไม่สนับสนุนการเขียนโปรแกรมลัทธิสินค้า เป็นเพียงผู้เสนอของการเชื่อมโยงแบบคงที่ (จากประสบการณ์ของฉัน) มักจะพลาดหรือประมาทความกังวลด้านความปลอดภัย การลิงก์แบบสแตติกสามารถเหมาะสมกับยูทิลิตี้แบบใช้ครั้งเดียวทำให้แอพพลิเคชั่นมีอยู่ในตัวเองและทำให้การกระจายง่ายขึ้นมาก แต่แอพใด ๆ ที่จะถูกนำไปใช้งานอย่างกว้างขวางหรือใช้ในการผลิตควรจะเชื่อมโยงกับห้องสมุดสาธารณะ ไม่มีข้อเสียที่แท้จริง: ในแอประดับนี้คุณต้องมีกระบวนการปรับใช้
โคดี้เกรย์

1
ตัวอย่างที่ดีของการเชื่อมโยงแบบสแตติกที่เหมาะสมคือที่ที่ฉันทำงาน - ระบบที่สำคัญในชีวิตที่ซับซ้อน เมื่อโมดูลที่สำคัญได้รับการทดสอบและอนุมัติสำหรับการทำงานแล้วพฤติกรรมนั้นจะต้องไม่เปลี่ยนแปลงหากไม่ผ่าน 'กระบวนการ' อย่างไรก็ตามไม่มีส่วนสำคัญในการปฏิบัติงานและไม่ใช้ชีวิตของระบบ (การเรียกเก็บเงินและการรายงาน) ต้องการการควบคุมที่เข้มงวดน้อยกว่าและใช้การเชื่อมโยงแบบไดนามิก
mattnz

7

จากมุมมองของนักพัฒนาซอฟต์แวร์การเชื่อมโยงแบบไดนามิกมักจะเพิ่มความเร็วในการคอมไพล์ / ลิงค์ / ทดสอบของคุณอย่างมาก

จากมุมมองการจัดการแพ็กเกจให้ใช้ libGL เป็นต้น ฉันมีการใช้งานที่แตกต่างกันประมาณหนึ่งโหลในตัวจัดการแพ็คเกจของฉันการ์ดแสดงผลทั่วไปและการ์ดเป้าหมายบางอัน หากไม่มีการเชื่อมโยงแบบไดนามิกจะต้องมีรุ่นโหลของแต่ละโปรแกรมที่เชื่อมโยงกับ libGL หรืออย่างอื่นคุณจะต้องกำหนดเลเยอร์เพิ่มเติมของสิ่งที่เป็นนามธรรมซึ่งไม่มีประสิทธิภาพเท่ากับการเรียกใช้ฟังก์ชัน

นึกถึงปัญหาความปลอดภัยในห้องสมุดยอดนิยมอย่าง Qt ด้วยการเชื่อมโยงแบบไดนามิกฉันสามารถอัปเดตแพ็คเกจนั้นแทนที่จะต้องระบุคอมไพล์ใหม่และปรับใช้ทุกแพ็คเกจที่ลิงก์ใน Qt

การเชื่อมโยงแบบสแตติกอาจมีข้อได้เปรียบในแอปพลิเคชันแบบปิดที่ปรับใช้อย่างอิสระ แต่ในการจัดการแพคเกจโอเพนซอร์สนั้นจะสร้างความเจ็บปวดมากกว่าความช่วยเหลือ


2
นี่เป็นเรื่องจริง (เร่งการพัฒนา) แต่มันน่าผิดหวังจริง ๆ ที่ทำให้เป็นการผลิต ตัวอย่างที่ยอมรับได้คือ Firefox จำนวนของความพยายามด้านวิศวกรรม (ในรูปแบบของแฮ็คที่น่าเกลียด) ซึ่งได้เร่งความเร็วในการเชื่อมโยงการแก้ปัญหาสัญลักษณ์การเชื่อมโยงแบบไดนามิกเพื่อให้ Firefox โหลดในเวลาที่เหมาะสมนั้นบ้าอย่างที่สุด ประสิทธิภาพที่ดีขึ้นมากสามารถบรรลุได้ด้วยต้นทุนทางวิศวกรรมที่น้อยลงหากพวกเขาเต็มใจที่จะเชื่อมโยงคงที่รหัสในโครงการทั้งหมดของพวกเขา (ในขณะที่ยังคงเชื่อมโยงไลบรารีระบบและปลั๊กอินแบบไดนามิกหากต้องการ)
.. GitHub หยุดช่วยน้ำแข็ง

5

ไลบรารีที่ใช้ร่วมกันเป็นที่ต้องการอย่างมากโดยผู้ดูแลการแจกจ่าย Linux เนื่องจากเหตุผลที่คุณ # 2 เป็นสิ่งสำคัญสำหรับพวกเขาเช่นเมื่อมีคนพบข้อบกพร่องด้านความปลอดภัยใน zlibพวกเขาไม่จำเป็นต้องคอมไพล์ใหม่ทุก ๆ โปรแกรมที่ใช้ zlib --- ไม่เพียง แต่จะทำให้พวกเขาใช้ CPU รอบมากขึ้นในการทำ การคอมไพล์ใหม่ทุกคนที่ใช้ distro จะต้องดาวน์โหลดโปรแกรมเหล่านั้นทั้งหมดอีกครั้ง ในขณะเดียวกันภายในชุดของแพ็กเกจที่จัดจำหน่ายโดยการกระจายนรกไม่ได้เป็นปัญหาเพราะทุกอย่างได้รับการทดสอบการทำงานกับชุดของไลบรารีนั้น

หากคุณกำลังสร้างซอฟต์แวร์บุคคลที่สามที่ต้องการห้องสมุดที่ไม่ได้อยู่ในการกระจายของคุณการลิงก์แบบคงที่ห้องสมุดเหล่านั้นอาจรบกวนน้อยกว่าทางเลือกอื่นและก็ใช้ได้

สิ่งสำคัญอื่น ๆ ที่ควรทราบคือ GNU libcและ GCC libstdc++มีองค์ประกอบที่ไม่สามารถทำงานได้อย่างน่าเชื่อถือหากห้องสมุดมีการเชื่อมโยงแบบคงที่ ปัญหาที่พบบ่อยที่สุดคือมีdlopenเพราะสิ่งที่คุณโหลดโมดูลที่มีdlopenอยู่ในตัวเองแบบไดนามิกlibc.so.6การเชื่อมโยงกับ นั่นหมายความว่าตอนนี้คุณมีไลบรารี่ C สองชุดในพื้นที่ที่อยู่ของคุณและความฮือฮาจะเกิดขึ้นเมื่อพวกเขาไม่เห็นด้วยกับการคัดลอกmallocโครงสร้างข้อมูลภายใน(ตัวอย่าง) มีสิทธิ์ มันแย่ลงเรื่อย ๆ : ฟังก์ชั่นมากมายที่ไม่ได้มีส่วนเกี่ยวข้องกับอะไรdlopenเช่นใช้gethostbynameและiconvใช้งานdlopenภายใน (เพื่อให้พฤติกรรมของพวกเขาสามารถกำหนดค่าได้เอง) โชคดีที่ ABI สำหรับ libc และ libstdc ++ มีความเสถียรมากดังนั้นคุณจึงไม่น่าจะพบปัญหาในการเชื่อมโยงพวกมันแบบไดนามิก


2

ฉันเห็นด้วยกับจุดสุดท้ายของ mattnz: คำถามนี้เป็นคำถามที่โหลด ถือว่าการเชื่อมโยงแบบสแตติกนั้นไม่ดี ฉันคิดได้สองเหตุผลว่าทำไมไม่เป็นเช่นนี้:

  • การเชื่อมโยงแบบสแตติกมีความปลอดภัย: หากมีการอัปเดตไลบรารีที่ใช้ร่วมกันซึ่งแอปพลิเคชันใช้ใหม่ นี่คือการเปลี่ยนแปลงรหัสนอกขอบเขตของการปรับปรุงอย่างเป็นทางการสำหรับแอปพลิเคชัน อาจไม่ผ่านการทดสอบ การเชื่อมโยงแบบคงที่หลีกเลี่ยงสิ่งนี้โดยไม่แชร์ไลบรารีจากภายนอก ฉันถือว่านี่เป็นข้อเสียของไลบรารีที่แชร์เนื่องจากความเสี่ยงนี้ จะเกิดอะไรขึ้นถ้าไลบรารี่ที่แชร์เวอร์ชันใหม่มีข้อบกพร่องใหม่ที่ทำให้แอปพลิเคชั่นรุ่นเก่าแตก

  • การเชื่อมโยงแบบคงที่ทำให้มั่นใจได้ว่าแอปพลิเคชันมีอยู่ในตัวเองมากขึ้น ในขณะที่ไลบรารีที่แบ่งใช้สามารถ colocated ด้วยการปฏิบัติการหลัก แต่บ่อยครั้งที่พวกเขาจะถูกฝากไว้ในสถานที่ที่ใช้ร่วมกัน แอปพลิเคชั่นที่เชื่อมโยงแบบคงที่นั้นง่ายต่อการตรวจสอบให้แน่ใจว่า "พกพา" ในแง่ของ "ไม่ต้องการการเปลี่ยนแปลงไฟล์ไดเรกทอรีหรือการตั้งค่าที่ระบบปฏิบัติการเป็นเจ้าของ" (คิดว่าไดเรกทอรี Windows รีจิสทรี / etc)


ขอบคุณสำหรับการปรับปรุงข้อได้เปรียบที่ฉันตั้งใจจะพูดถึง อย่างไรก็ตามหากคุณเห็นแพ็คเกจส่วนใหญ่ที่จัดทำโดยลีนุกซ์ดิสทริบิวชั่น, พวกเขาจะไม่ถูกรวบรวมแบบคงที่. มันจะดูเหมือนว่าการสะสมคงขมวดคิ้วอย่างน้อยจากจุดเชื่อมต่อภายนอกของมุมมอง
Margian Florian

1
ไลบรารีแบบไดนามิกบนระบบปฏิบัติการทุกระบบในทุกวันนี้มีการทำเพจตามความต้องการ เฉพาะหน้าที่ใช้งานจริงเท่านั้นที่อยู่ในหน่วยความจำ หากแอปพลิเคชั่นหลายตัวใช้ฟังก์ชั่นเดียวกันพวกเขาจะแชร์หน่วยความจำและใช้น้อยกว่ากรณีไลบรารีแบบสแตติก หากมีหลายแอปที่ใช้ฟังก์ชันการทำงานที่แตกต่างกันในไลบรารีเดียวกันทั้งสองชุดของการทำงานจะได้รับการเพจเพจโดยมีผลกระทบใกล้เคียงกับแนวทางแบบคงที่
Alan Shutko

@ AlanShutko ฉันพยายามและพิมพ์ซ้ำส่วนนั้นหลายวิธีเนื่องจากสิ่งที่คุณพูดถึง ไม่มีการรับประกันจริงทั้งสองทางแม้ว่าระบบปฏิบัติการที่ทันสมัยจะนำเสนอประสิทธิภาพของไลบรารีที่ใช้ร่วมกันโดยมีค่าใช้จ่ายคงที่ ฉันจะแก้ไขอีกครั้ง

@ Snowman ฉันคิดว่าประเด็นพื้นฐานคือในระบบปฏิบัติการจริงที่ให้การเชื่อมโยงแบบไดนามิก (ฉันไม่รู้ระบบปฏิบัติการใด ๆ ที่ใช้การเชื่อมโยงแบบไดนามิก แต่ไม่ต้องการเพจจิ้ง) จุดที่สองของคุณไม่เก็บน้ำ: หน่วยความจำไม่ได้ใช้จริง ยกเว้นว่ามีการใช้งานฟังก์ชันและหน่วยความจำที่ใช้โดยไลบรารีแบบไดนามิกสามารถใช้ร่วมกันระหว่างโปรแกรมต่าง ๆ ที่ใช้งานได้ทำให้การใช้หน่วยความจำสำหรับรุ่นแบบไดนามิกมีประสิทธิภาพมากกว่าไม่น้อยกว่า เหตุผลแรกและข้อที่สามของคุณนั้นถูกต้อง แต่ฉันแค่ลบข้อที่สองด้วยสมมติฐานที่เหมือนจริงใด ๆ มันก็ผิด
จูลส์

@Jules ฉันเห็นด้วยมันเป็นประเด็นที่เป็นปัญหาและความถูกต้องน่าสงสัยในระบบปฏิบัติการที่ทันสมัย ฉันลบมัน

1

ห้องสมุดแบบคงที่และแบบไดนามิกแต่ละแห่งมีการใช้งานของตนเอง การดูแอปพลิเคชันเดียวในขอบเขตที่เราได้รับความคิดที่แตกต่างกันเกี่ยวกับสิ่งที่จำเป็นและสิ่งที่ไม่

การลิงก์แบบสแตติกทำให้การปรับใช้แอปพลิเคชันง่ายขึ้นอย่างมาก ไม่ต้องตรวจจับและจัดการกับรุ่นที่แตกต่างกัน เพียงอบและปรับใช้

ข้อได้เปรียบที่ชัดเจนของไลบรารีแบบไดนามิกคือความสามารถในการใช้การอัปเดตอย่างอิสระ

นี่คือหนึ่งในเหตุผลที่ฉันเกลียด maven และอื่น ๆ ที่คล้ายกันเชื่อมโยงผู้สร้างโครงการสำหรับ java พวกเขาคาดหวังว่าจะมีไลบรารี่รุ่นเดียวให้บริการตาม URL ที่กำหนดตลอดไป ไม่เข้าใจปัญหาที่เกิดขึ้นใน 10 ปีเมื่อไม่มีใครสามารถคอมไพล์แอปพลิเคชันได้เพราะแหล่งที่มาและขวดทั้งหมดหายไป


มีเหตุผลใดเป็นพิเศษหรือไม่ว่าทำไมโปรแกรมที่ใช้FooLib1.8ในการรวมรหัสสำหรับไลบรารีนั้นในแพคเกจปฏิบัติการของพวกเขาด้วยวิธีมาตรฐานเพื่อให้โปรแกรมอัพเกรดที่มาพร้อมกับFooLib1.9การอัพเกรดหรือดาวน์เกรดนั้นเป็นไปไม่ได้? วิธีที่รหัสถูกเก็บไว้ใน Classic Macintosh จะทำให้มันง่ายมาก มีเหตุผลใดที่ระบบของวันนี้ไม่ควรจะทำได้ดีกว่านี้?
supercat

@supercat คุณหมายถึงว่าทุกรุ่นของห้องสมุดที่กำหนดจะมีอยู่ในระบบ? ไม่แน่ใจว่าฉันเข้าใจคำถาม คำถาม OP ถูกนำไปสู่ไลบรารีที่แบ่งใช้ทั่วทั้งระบบมากกว่ากับสแตติกไลบรารีที่จะถูกรวมเข้าด้วยกัน
กรอบจำนวนมาก

ประเด็นของฉันคือการมีแพ็คเกจที่สามารถเรียกใช้งานได้นั้นรวมถึงไลบรารีทั้งหมดที่จำเป็นต้องมีเพื่อไม่ให้มีความเป็นไปได้ในการอัพเกรดไลบรารีที่อยู่ในนั้น ดังนั้นฉันไม่ทราบว่าฉันจะพิจารณาถึงความสามารถในการอัปเกรดสิ่งต่าง ๆ หลังจากการปรับใช้เพื่อประโยชน์ของการไม่รวมแอปพลิเคชันเข้ากับไลบรารี
supercat

หากสิทธิ์การใช้งานของไลบรารี่ที่กำหนดนั้นอนุญาตให้คุณแจกจ่ายมันไปกับแพ็คเกจของคุณได้นั่นเป็นวิธีที่แนะนำให้ทำเสมอ มันลดจำนวนการพึ่งพาจากภายนอก เนื่องจากคุณจะแจกจ่ายทุกอย่างดังนั้นช่างอัพเกรดหรือแพตช์จะทำงานในลักษณะเดียวกันกับแบบคงที่หรือแบบไดนามิก การแพตช์มักขึ้นอยู่กับฐานสามเหลี่ยม จะไม่มีความแตกต่าง
มันฝรั่งทอดกรอบจำนวนมาก
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.