CodeBlanks Logo Icon CodeBlanks

Semaphore

  • C kursu
  • İleri seviye
  • Ders 35/83
  • 5 dk

semget ve semop ile semafor öğrenirsin.

Semaphore

Semafor, süreçler arası senkronizasyon için kullanılan bir sayaçtır. semget(key, nsems, flags) ile küme oluşturulur; IPC_PRIVATE yeni küme üretir. semctl(semid, 0, SETVAL, val) ile başlangıç değeri verilir.

İşlem struct sembuf ile tanımlanır: {sem_num, sem_op, sem_flg}. sem_op = -1 bekleme (P), sem_op = +1 sinyal (V) işlemidir. semop(semid, &op, 1) ile uygulanır. Eğer sayaç sıfırsa -1 işlemi bekler; +1 işlemi bekleyeni uyandırır. semctl(semid, 0, IPC_RMID) ile küme silinir.

Parent signal, child wait deseni

Semaforu olay sıralaması için kullanabilirsin. Ebeveyn fork öncesi semctl(semid, 0, SETVAL, 0) ile sıfırlar. Çocuk struct sembuf op = {0, -1, 0}; semop(semid, &op, 1); ile bekler; sayaç sıfır olduğundan bloklanır.

Ebeveyn işini bitirince struct sembuf op = {0, 1, 0}; semop(semid, &op, 1); ile sinyal verir. Bu, çocuğun -1 işlemini serbest bırakır; çocuk uyanır ve printf yapar. Böylece çocuğun ebeveynden sonra çalıştığı garanti edilir. wait(NULL) ve semctl(semid, 0, IPC_RMID) ile temizlik yapılır.

Uygulama Semafor ile sıralama

int semid = semget(IPC_PRIVATE, 1, 0600 | IPC_CREAT); ile küme kur. semctl(semid, 0, SETVAL, 0); ile sıfırla. pid_t pid = fork(); ile çocuk oluştur. Çocukta struct sembuf op = {0, -1, 0}; semop(semid, &op, 1);, printf("çocuk geldi\n");, _exit(0);. Ebeveynde struct sembuf op = {0, 1, 0}; semop(semid, &op, 1);, wait(NULL);, semctl(semid, 0, IPC_RMID);.

Başlangıç kodu

main.c
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/wait.h>
#include <unistd.h>

// semafor kümesi kur ve sıfırla
// fork ile çocuk beklesin
// ebeveyn sinyal verip temizlesin

int main(void) {
    return 0;
}

Örnek çözüm

main.c
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/wait.h>
#include <unistd.h>

int main(void) {
    int semid = semget(IPC_PRIVATE, 1, 0600 | IPC_CREAT);
    semctl(semid, 0, SETVAL, 0);
    pid_t pid = fork();
    if (pid == 0) {
        struct sembuf op = {0, -1, 0};
        semop(semid, &op, 1);
        printf("çocuk geldi\n");
        _exit(0);
    }
    struct sembuf op = {0, 1, 0};
    semop(semid, &op, 1);
    wait(NULL);
    semctl(semid, 0, IPC_RMID);
    return 0;
}

Beklenen çıktı

çocuk geldi

Soru ve cevaplar

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

1 Semafor fonksiyonlarını eşle

Kavram Anlamı
semget Küme oluşturur
semop İşlem uygular
semctl Değer atar/siler
sembuf İşlem tanımı

2 struct sembuf içinde sem_op = -1 ne yapar?

  • Küme silme
  • Sinyal (V) işlemi
  • Bekleme (P) işlemi Doğru cevap
  • Değer atama

Açıklama: sem_op = -1 bekleme (P) işlemidir; sayaç sıfırsa bekler.

3 semop çağrısı

Soru
struct sembuf op = {0, 1, 0}; semop(semid, &op, ____);
Cevap
struct sembuf op = {0, 1, 0}; semop(semid, &op, 1);

Açıklama: Üçüncü parametre işlem sayısıdır; tek işlem için 1 verilir.

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