CodeBlanks Logo Icon CodeBlanks

IPC ve senkronizasyon

  • C kursu
  • İleri seviye
  • Ders 82/83
  • 6 dk

Pipe ve semafor ile IPC ve senkronizasyon yazarsın.

IPC ve senkronizasyon

Bu derste ipc_setup işlevini tanımlayacaksın. pipe ile iki üçlü bir kanal oluşturur, fork ile çocuk süreç açar. Çocuk write ile "ipc" yazar, ebeveyn read ile okur.

Adımlar: int p[2]; pipe(p);, pid_t pid = fork();, çocuksa close(p[0]), write(p[1], "ipc", 3), close(p[1]), _exit(0). Ebeveyn close(p[1]), read(p[0], buf, 3), close(p[0]), wait(NULL). Bu desen, süreçler arası iletişimin temelidir. wait çocuğun bitmesini senkronize eder.

Pipe akışı

pipe(p) iki tanıtıcı verir: p[0] okuma, p[1] yazma ucu. Çocuk yazma üçünü kullanır, okuma üçünü kapatır. Ebeveyn tam tersi.

Çocuk: close(p[0]); write(p[1], "ipc", 3); close(p[1]); _exit(0);. Ebeveyn: close(p[1]); char buf[8] = {0}; int n = read(p[0], buf, 3); close(p[0]); wait(NULL); return n > 0 ? 1 : 0;. read bloklanır; çocuk yazana kadar bekler. wait(NULL) çocuğun bitmesini sağlar. Main'de int r = ipc_setup(); ve printf("ipc: %d\n", r);. Çıktıya "ipc: 1" eklenir.

Uygulama ipc_setup'ı ekle

int ipc_setup(void) yaz: int p[2]; pipe(p);, pid_t pid = fork();, çocuksa close(p[0]); write(p[1], "ipc", 3); close(p[1]); _exit(0);, ebeveyn close(p[1]); char buf[8] = {0}; int n = read(p[0], buf, 3); close(p[0]); wait(NULL); return n > 0 ? 1 : 0;. main'e int r = ipc_setup(); ve printf("ipc: %d\n", r); ekle.

Başlangıç kodu

main.c
#include <stdio.h>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>

int worker_init(void);
int server_setup(void);
int ipc_setup(void);

int worker_count = 0;
pthread_mutex_t worker_lock = PTHREAD_MUTEX_INITIALIZER;

void *worker_fn(void *arg) {
    (void)arg;
    pthread_mutex_lock(&worker_lock);
    worker_count++;
    pthread_mutex_unlock(&worker_lock);
    return NULL;
}

int worker_init(void) {
    pthread_t t;
    pthread_create(&t, NULL, worker_fn, NULL);
    pthread_join(t, NULL);
    return 1;
}

int server_setup(void) {
    int fd = socket(AF_UNIX, SOCK_STREAM, 0);
    struct sockaddr_un addr;
    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, "/tmp/cb_p.sock", sizeof(addr.sun_path) - 1);
    unlink("/tmp/cb_p.sock");
    bind(fd, (struct sockaddr *)&addr, sizeof(addr));
    listen(fd, 1);
    return fd;
}

// ipc_setup fonksiyonunu yaz: pipe ile kanal oluştur, fork ile çocuk aç
// çocuk write ile "ipc" yazar, ebeveyn read ile okur

int main(void) {
    printf("Proje hazır\n");
    worker_init();
    printf("sayaç: %d\n", worker_count);
    int sfd = server_setup();
    printf("soket: %d\n", sfd >= 0 ? 1 : 0);
    // ipc_setup çağır ve "ipc: 1" yazdır
    return 0;
}

Örnek çözüm

main.c
#include <stdio.h>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>

int worker_init(void);
int server_setup(void);
int ipc_setup(void);

int worker_count = 0;
pthread_mutex_t worker_lock = PTHREAD_MUTEX_INITIALIZER;

void *worker_fn(void *arg) {
    (void)arg;
    pthread_mutex_lock(&worker_lock);
    worker_count++;
    pthread_mutex_unlock(&worker_lock);
    return NULL;
}

int worker_init(void) {
    pthread_t t;
    pthread_create(&t, NULL, worker_fn, NULL);
    pthread_join(t, NULL);
    return 1;
}

int server_setup(void) {
    int fd = socket(AF_UNIX, SOCK_STREAM, 0);
    struct sockaddr_un addr;
    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, "/tmp/cb_p.sock", sizeof(addr.sun_path) - 1);
    unlink("/tmp/cb_p.sock");
    bind(fd, (struct sockaddr *)&addr, sizeof(addr));
    listen(fd, 1);
    return fd;
}

int ipc_setup(void) {
    int p[2];
    pipe(p);
    pid_t pid = fork();
    if (pid == 0) {
        close(p[0]);
        write(p[1], "ipc", 3);
        close(p[1]);
        _exit(0);
    }
    close(p[1]);
    char buf[8] = {0};
    int n = read(p[0], buf, 3);
    close(p[0]);
    wait(NULL);
    return n > 0 ? 1 : 0;
}

int main(void) {
    printf("Proje hazır\n");
    worker_init();
    printf("sayaç: %d\n", worker_count);
    int sfd = server_setup();
    printf("soket: %d\n", sfd >= 0 ? 1 : 0);
    int r = ipc_setup();
    printf("ipc: %d\n", r);
    return 0;
}

Beklenen çıktı

Proje hazır
sayaç: 1
soket: 1
ipc: 1

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 fork başarılı olursa ne döndürür?

  • Her zaman 0
  • Çocuğa 0, ebeveyne PID Doğru cevap
  • Hiçbir şey
  • Her zaman -1

Açıklama: fork çocuğa 0, ebeveyne çocuk PID döndürür.

2 IPC adımlarını eşle

Kavram Anlamı
pipe Kanal oluştur
fork Çocuk süreç
write Veri gönder
wait Çocuğu bekle

3 çocuk dalı

Soru
pid_t pid = fork(); if (pid == ____) { close(p[0]); write(p[1], "ipc", 3); _exit(0); }
Cevap
pid_t pid = fork(); if (pid == 0) { close(p[0]); write(p[1], "ipc", 3); _exit(0); }

Açıklama: fork çocuğa 0 döndürür; çocuk dalı budur.

İleri seviye bölümündeki tüm dersler