C Programming A to Z (পর্ব-৭): মাল্টিথ্রেডিং, সকেট নেটওয়ার্কিং ও প্রো বিল্ড সিস্টেম

Blog / C Programming A to Z (পর্ব-৭): মাল্টিথ্রেডিং, সকেট নেটওয়ার্কিং ও প্রো বিল্ড সিস্টেম

C Programming A to Z (পর্ব-৭): মাল্টিথ্রেডিং, সকেট নেটওয়ার্কিং ও প্রো বিল্ড সিস্টেম Detail Page

C Programming A to Z (পর্ব-৭): মাল্টিথ্রেডিং, সকেট নেটওয়ার্কিং ও প্রো বিল্ড সিস্টেম

C Programming A to Z (পর্ব-৭) মাল্টিথ্রেডিং, সকেট নেটওয়ার্কিং ও প্রো বিল্ড সিস্টেম

আমরা C প্রোগ্রামিংয়ের এত গভীরে চলে এসেছি যে এখন সময় এসেছে প্রোগ্রামকে “জীবন্ত” করে তোলার। আপনার লেখা প্রোগ্রাম যদি শুধু নিজের মধ্যে ডেটা প্রসেস করে, তাহলে তা একটা দ্বীপের মতো। কিন্তু বাস্তবিক সফটওয়্যার (যেমন: সার্ভার, গেমস, ব্রাউজার) একসাথে হাজার হাজার কাজ করে এবং নেটওয়ার্কের মাধ্যমে অন্যের সাথে কথা বলে।

আজকের এই পর্বে আমরা C-এর সেই দুটি সবচেয়ে ভয়ংকর অস্ত্র হাতে নেবো:
১. থ্রেড (Thread) – যা দিয়ে প্রোগ্রাম একসাথে একাধিক কাজ করে (প্যারালালিজম)।
২. সকেট (Socket) – যা দিয়ে প্রোগ্রাম নেটওয়ার্কের মাধ্যমে অন্যদের সাথে যোগাযোগ করে।

প্রস্তুত? তাহলে সিস্টেম প্রোগ্রামিং-এর রাজ্যে স্বাগতম! 🏰🔥


🔄 পর্ব-৬ এর রিক্যাপ ও সিস্টেম প্রোগ্রামিং-এর ভূমিকা

আমরা গত পর্বে BST, গ্রাফ এবং Big-O কমপ্লেক্সিটি শিখেছি। আজ আমরা সেই জ্ঞানকে কাজে লাগিয়ে প্রোগ্রামকে মাল্টি-কোর প্রসেসরে চালাবো এবং নেটওয়ার্কের মাধ্যমে ডেটা আদান-প্রদান করাবো। এটি একটু চ্যালেঞ্জিং, কিন্তু বিশ্বাস করুন, শেষ পর্যন্ত এটি সবচেয়ে মজার অংশ!


📚 অধ্যায় ৩৬: স্ট্যাটিক বনাম ডায়নামিক লাইব্রেরি (Static vs Dynamic Libraries)

আপনি যখন বড় প্রোজেক্ট তৈরি করেন, তখন একই কোড (যেমন: ম্যাথ ফাংশন) বারবার লেখা ভালো অভ্যাস নয়। আমরা সেগুলোকে লাইব্রেরি-তে রূপান্তর করি।

স্ট্যাটিক লাইব্রেরি (.a – Static):

  • কম্পাইল করার সময় লাইব্রেরির কোড আপনার প্রোগ্রামের সাথে মিশে যায়।
  • সুবিধা: প্রোগ্রাম সেলফ-কন্টেইন্ড (পোর্টেবল)।
  • অসুবিধা: ফাইলের সাইজ বড় হয়, এবং লাইব্রেরি আপডেট করলে পুরো প্রোগ্রাম রিকম্পাইল করতে হয়।

কীভাবে বানাবেন?

bash

gcc -c math_utils.c          # math_utils.o তৈরি
ar rcs libmath.a math_utils.o # স্ট্যাটিক লাইব্রেরি তৈরি
gcc main.c -L. -lmath -o program # লাইব্রেরি লিংক করা

ডায়নামিক লাইব্রেরি (.so – Shared Object / .dll – Windows):

  • রানটাইমে লোড হয়। একাধিক প্রোগ্রাম একই লাইব্রেরি শেয়ার করতে পারে।
  • সুবিধা: ফাইলের সাইজ ছোট, লাইব্রেরি আপডেট করলে প্রোগ্রাম রিকম্পাইল করতে হয় না (শুধু রিস্টার্ট)।

কীভাবে বানাবেন?

bash

gcc -fPIC -c math_utils.c     # পজিশন-ইন্ডিপেন্ডেন্ট কোড
gcc -shared -o libmath.so math_utils.o # শেয়ার্ড লাইব্রেরি
gcc main.c -L. -lmath -o program

💡 পেশাদার টিপস: লিনাক্সের অধিকাংশ সফটওয়্যার (যেমন: libc.so) ডায়নামিক লাইব্রেরি ব্যবহার করে।


🛠️ অধ্যায় ৩৭: মেকফাইল (Makefile) – একটি ক্লিকে পুরো প্রোজেক্ট কম্পাইল করুন

বড় প্রোজেক্টে ২০-৩০টি .c ফাইল থাকে। প্রতিবার gcc টাইপ করা অসম্ভব। Makefile হলো একটি স্ক্রিপ্ট যা বলে দেয় কোন ফাইল আগে কম্পাইল হবে এবং কীভাবে লিংক হবে।

একটি সাধারণ Makefile:

makefile

CC = gcc
CFLAGS = -Wall -g -Iinclude
TARGET = my_app
SRCS = main.c math_utils.c file_utils.c
OBJS = $(SRCS:.c=.o)

# ডিফল্ট টার্গেট
all: $(TARGET)

# লিংকিং (Executable বানানো)
$(TARGET): $(OBJS)
	$(CC) -o $@ $^

# কম্পাইলেশন (.c থেকে .o বানানো)
%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@

# ক্লিনআপ (পুরনো ফাইল ডিলিট)
clean:
	rm -f $(OBJS) $(TARGET)

# রান করার টার্গেট
run: $(TARGET)
	./$(TARGET)

কীভাবে ব্যবহার করবেন: টার্মিনালে শুধু make টাইপ করুন, পুরো প্রোজেক্ট কম্পাইল হয়ে যাবে! make clean দিলে সব ফাইল পরিষ্কার হবে। এটি শিখলে আপনি যেকোনো ওপেন সোর্স প্রোজেক্ট কম্পাইল করতে পারবেন।


🧵 অধ্যায় ৩৮: পিওএসআইএক্স থ্রেড (Pthreads) – একসাথে একাধিক কাজ করা

ধরা যাক, আপনাকে ১০০টি ছবি প্রসেস করতে হবে। যদি একে একে করেন, সময় লাগবে ১০০ সেকেন্ড। কিন্তু আপনার কম্পিউটারে যদি ৪টি কোর থাকে, তাহলে ৪টি থ্রেড তৈরি করে কাজ ভাগ করে দিলে সময় কমে ২৫ সেকেন্ডে!

C-তে থ্রেড তৈরির জন্য pthread লাইব্রেরি ব্যবহার হয় (Linux/macOS-এ)।

c

#include <stdio.h>
#include <pthread.h>
#include <unistd.h> // sleep() এর জন্য

// থ্রেড ফাংশন
void* printNumbers(void* arg) {
    int id = *(int*)arg;
    for (int i = 1; i <= 5; i++) {
        printf("থ্রেড %d: %d\n", id, i);
        sleep(1); // ১ সেকেন্ড বিরতি
    }
    return NULL;
}

int main() {
    pthread_t t1, t2;
    int id1 = 1, id2 = 2;

    // দুটি থ্রেড তৈরি
    pthread_create(&t1, NULL, printNumbers, &id1);
    pthread_create(&t2, NULL, printNumbers, &id2);

    // থ্রেড শেষ হওয়া পর্যন্ত অপেক্ষা (Join)
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    printf("✅ সব থ্রেড শেষ!\n");
    return 0;
}

কম্পাইল করার নিয়ম: gcc program.c -pthread -o program (অবশ্যই -pthread ফ্ল্যাগ দিতে হবে)।


🔒 অধ্যায় ৩৯: মিউটেক্স (Mutex) ও থ্রেড সেফটি – রেস কন্ডিশন থেকে বাঁচুন

যখন একাধিক থ্রেড একই ভেরিয়েবলে পরিবর্তন আনে, তখন রেস কন্ডিশন (Race Condition) নামক ভয়াবহ সমস্যা হয়। যেমন: দুটি থ্রেড যদি একসাথে একটি কাউন্টার বাড়ায়, তাহলে মান ১ কম বা বেশি হয়ে যেতে পারে।

এই সমস্যা সমাধানে মিউটেক্স (Mutex) ব্যবহার করি। এটি একটি লক, যা একবার শুধু একজনই ধারণ করতে পারে।

c

#include <stdio.h>
#include <pthread.h>

int counter = 0;
pthread_mutex_t lock; // মিউটেক্স ডিক্লেয়ার

void* increment(void* arg) {
    for (int i = 0; i < 100000; i++) {
        pthread_mutex_lock(&lock);   // লক নেওয়া
        counter++;                   // ক্রিটিক্যাল সেকশন
        pthread_mutex_unlock(&lock); // লক ছেড়ে দেওয়া
    }
    return NULL;
}

int main() {
    pthread_t t1, t2;
    pthread_mutex_init(&lock, NULL); // মিউটেক্স ইনিশিয়ালাইজ

    pthread_create(&t1, NULL, increment, NULL);
    pthread_create(&t2, NULL, increment, NULL);
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    pthread_mutex_destroy(&lock); // মিউটেক্স ডেস্ট্রয়
    printf("কাউন্টারের মান: %d\n", counter); // ঠিক ২০০০০০ আসবে!
    return 0;
}

💡 গুরুত্বপূর্ণ: মিউটেক্স না থাকলে কাউন্টারের মান ২০০০০০-এর কম আসত। ডেটাবেস, ফাইল রাইট—সব জায়গায় মিউটেক্স ব্যবহার হয়।


🌐 অধ্যায় ৪০: সকেট প্রোগ্রামিং (TCP) – দুটি কম্পিউটারের মধ্যে কথোপকথন

সকেট হলো নেটওয়ার্কের দরজা। আমরা দুটি প্রোগ্রাম লিখব—একটি সার্ভার (যে শোনে) এবং একটি ক্লায়েন্ট (যে বার্তা পাঠায়)।

সার্ভার কোড (server.c):

c

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

int main() {
    int server_fd, new_socket;
    struct sockaddr_in address;
    int opt = 1;
    char buffer[1024] = {0};
    char *message = "Hello from Server!";

    // ১. সকেট তৈরি
    server_fd = socket(AF_INET, SOCK_STREAM, 0);
    setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    // ২. অ্যাড্রেস সেট করা
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(8080);

    // ৩. বাইন্ড (পোর্টের সাথে সংযুক্ত)
    bind(server_fd, (struct sockaddr *)&address, sizeof(address));

    // ৪. লিসেন (ক্লায়েন্টের জন্য অপেক্ষা)
    listen(server_fd, 3);
    printf("🖥️ সার্ভার ৮০৮০ পোর্টে লিসেন করছে...\n");

    // ৫. ক্লায়েন্টকে গ্রহণ (Accept)
    new_socket = accept(server_fd, NULL, NULL);

    // ৬. ক্লায়েন্টকে বার্তা পাঠানো
    send(new_socket, message, strlen(message), 0);
    printf("📤 বার্তা পাঠানো হয়েছে!\n");

    close(new_socket);
    close(server_fd);
    return 0;
}

ক্লায়েন্ট কোড (client.c):

c

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

int main() {
    int sock = 0;
    struct sockaddr_in serv_addr;
    char buffer[1024] = {0};

    // ১. সকেট তৈরি
    sock = socket(AF_INET, SOCK_STREAM, 0);

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(8080);
    inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr); // লোকালহোস্ট

    // ২. সার্ভারে কানেক্ট করা
    connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));

    // ৩. সার্ভার থেকে বার্তা পড়া
    read(sock, buffer, 1024);
    printf("📩 সার্ভার থেকে বার্তা: %s\n", buffer);

    close(sock);
    return 0;
}

🔥 রান করবেন কীভাবে: প্রথমে টার্মিনাল-১ এ ./server চালান, তারপর টার্মিনাল-২ এ ./client চালান। দেখবেন ক্লায়েন্ট “Hello from Server!” বার্তা পেয়েছে! এটি প্রোগ্রামিং জীবনের অন্যতম সেরা অনুভূতি।


🛑 অধ্যায় ৪১: সিগন্যাল হ্যান্ডলিং – Ctrl+C ধরা

আপনি যখন Ctrl+C চাপেন, প্রোগ্রাম হঠাৎ বন্ধ হয়ে যায়। কিন্তু আপনার প্রোগ্রাম যদি ফাইলে ডেটা লেখে, তাহলে হঠাৎ বন্ধ হয়ে ডেটা নষ্ট হতে পারে। সিগন্যাল হ্যান্ডলার দিয়ে আমরা সেই বোতাম ধরে ফেলতে পারি।

c

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void sigint_handler(int sig) {
    printf("\n🛑 প্রোগ্রাম বন্ধ করা হচ্ছে... শেষ মুহূর্তের কাজ শেষ করছি!\n");
    // এখানে ফাইল ক্লোজ, মেমোরি ফ্রি ইত্যাদি করুন
    exit(0); // প্রস্থান
}

int main() {
    // Ctrl+C (SIGINT) সিগন্যাল ধরা
    signal(SIGINT, sigint_handler);

    printf("প্রোগ্রাম চলছে। বন্ধ করতে Ctrl+C চাপুন।\n");
    while (1) {
        printf("কাজ করছি...\n");
        sleep(2);
    }
    return 0;
}

এটি লাইফ সেভার! বড় সার্ভারে এটি ব্যবহার করলে প্রোগ্রাম হঠাৎ ক্র্যাশ না করে মার্জিতভাবে বন্ধ হয়।


🏗️ অধ্যায় ৪২: ফাইনাল প্রোজেক্ট – ‘মাল্টি-থ্রেডেড চ্যাট সার্ভার’

এখন আমরা সবকিছু একসাথে ফেলব। আমরা একটি সার্ভার বানাবো যা একাধিক ক্লায়েন্টকে একসাথে হ্যান্ডেল করতে পারে (প্রতি ক্লায়েন্টের জন্য একটি করে থ্রেড তৈরি করবে) এবং বার্তা গ্রহণ করে ফাইলে লগ করবে।

সার্ভারের মূল লজিক (ধারণাগত):

  1. সার্ভার সকেট খোলে এবং লিসেন করে।
  2. একটি while লুপে accept() কল করে নতুন ক্লায়েন্ট এলে তার জন্য একটি থ্রেড তৈরি করে (যোগাযোগের সকেটটি থ্রেডে পাঠিয়ে দেয়)।
  3. থ্রেড ফাংশনটি ক্লায়েন্ট থেকে বার্তা পড়ে, ফাইলে সেভ করে এবং ক্লায়েন্টকে “বার্তা প্রাপ্ত” বলে জানায়।

c

// সার্ভারের মূল স্ট্রাকচার (পূর্ণ কোড কমান্ডের জন্য সংক্ষিপ্ত)
void *handle_client(void *arg) {
    int client_socket = *(int*)arg;
    char buffer[1024];
    while (read(client_socket, buffer, 1024) > 0) {
        printf("📨 ক্লায়েন্ট থেকে: %s\n", buffer);
        // ফাইলে সেভ করুন
        send(client_socket, "ACK: বার্তা পেয়েছি!", 20, 0);
    }
    close(client_socket);
    return NULL;
}

⚡ চ্যালেঞ্জ: উপরের স্ট্রাকচারটি নিজে সম্পূর্ণ করুন। এটি আপনার পোর্টফোলিওতে একটি “মাল্টি-থ্রেডেড TCP সার্ভার” হিসেবে জ্বলজ্বল করবে।


🏁 চূড়ান্ত আর্কিটেক্টের পথচলা

প্রিয় প্রোগ্রামার, আপনি এখন C-এর শেষ সীমান্ত অতিক্রম করেছেন। আপনি জানেন কীভাবে প্রোগ্রাম একসাথে একাধিক কাজ করে (Threads), কীভাবে নেটওয়ার্কে কথা বলে (Sockets), এবং কীভাবে পেশাদার টুলস (Makefile, Libraries) ব্যবহার করতে হয়।

“C Programming A to Z” – এই ৭ পর্বের যাত্রা এখানেই শেষ হচ্ছে। কিন্তু আপনার যাত্রা তো এখানেই শেষ নয়, বরং এটি সবে শুরু!

এখন আপনি কী করবেন?
১. লিনাক্স কার্নেল মডিউল: নিজের একটি ছোট ড্রাইভার লিখুন। C দিয়ে হার্ডওয়্যার নিয়ন্ত্রণ করুন।
২. আরটিওএস (RTOS): এমবেডেড সিস্টেমে ফ্রিটার ওএস (FreeRTOS) নিয়ে কাজ করুন।
৩. ইউজারল্যান্ড প্রোজেক্ট: এনক্রিপ্টেড চ্যাট অ্যাপ, কাস্টম ডেটাবেস ইঞ্জিন বা একটি ওয়েব সার্ভার (যেমন: Nginx-এর ছোট সংস্করণ) বানানোর চেষ্টা করুন।

আপনি আজ যে জ্ঞান অর্জন করলেন, তা বিশ্বের যেকোনো প্রিমিয়ার টেক কোম্পানিতে (Google, Microsoft, Intel) কাজে লাগবে। C হলো সেই ভাষা যা হার্ডওয়্যারের সাথে সরাসরি কথা বলে, এবং আপনি এখন সেই ভাষায় সাবলীল।

ToLearnTeam পরিবার আপনার এই অসাধারণ অর্জনের জন্য গর্বিত। অসংখ্য ধন্যবাদ আমাদের সঙ্গে এই যাত্রায় থাকার জন্য। এখন নেটওয়ার্ক জুড়ে আপনার কোডের জয়গান হোক!

আপনার হাতের কিবোর্ডই এখন আপনার অস্ত্র। তৈরি করুন, ভাঙুন, আর নতুন কিছু তৈরি করুন। পৃথিবী অপেক্ষা করছে আপনার জন্য! 

Full Advanced Course in C

  1. C Programming A to Z: শূন্য থেকে বিশেষজ্ঞ হওয়ার সম্পূর্ণ গাইড
  2. C Programming A to Z (পর্ব-২): মেমোরি, ম্যাক্রো ও রিয়েল-লাইফ প্রোজেক্ট
  3. C Programming A to Z (পর্ব-৩): ডেটা স্ট্রাকচার, বিটওয়াইজ ম্যাজিক ও মাল্টি-ফাইল প্রোজেক্ট
  4. C Programming A to Z (পর্ব-৪): অ্যালগরিদম, স্ট্যাক, কিউ ও গ্র্যান্ড ফাইনাল প্রোজেক্ট
  5. C Programming A to Z (বোনাস পর্ব-৫): প্রো টুলচেইন, বাইনারি ফাইল ও ডিবাগিং ম্যাজিক
  6. C Programming A to Z (পর্ব-৬): ট্রি, গ্রাফ, বিগ-ও নোটেশন ও ক্যাপস্টোন প্রোজেক্ট
  7. C Programming A to Z (পর্ব-৭): মাল্টিথ্রেডিং, সকেট নেটওয়ার্কিং ও প্রো বিল্ড সিস্টেম
  8. C Programming A to Z (পর্ব-৮): প্রোফাইলিং, সিকিউরিটি, কন্ডিশন ভেরিয়েবল ও প্রোডাকশন লগার

Leave a Reply

Welcome to To Learn Team, a dynamic educational platform where knowledge meets collaboration. Designed for students, educators, and lifelong learners, we provide a curated hub of interactive study groups, expert tutorials, and comprehensive resources across diverse subjects. We believe that learning is most powerful when done together. By uniting a global community, we transform curiosity into confidence and individual aspirations into shared achievements. Join the To Learn Team today—elevate your intellect and grow with us!

Get In Touch

Address

Dhaka, Bangladesh

Email

abir43tee@gmail.com

Phone

+880 1711427737

Quick Search