Sobes.tech
Middle

Workshopping nedir?

sobes.tech yapay zeka

AI'dan gelen yanıt

İş çalma (work stealing), çok iş parçacıklı sistemlerde yük dengeleme mekanizmasıdır; burada pasif çalışan bir işçi (worker), meşgul olan başka bir işçinin kuyruğundan görev çalar.

Ana özellikler:

  • Merkezi olmayan: Her işçi kendi yerel görev kuyruğunu yönetir.
  • Aktif: Pasif işçi, diğerlerinden aktif olarak iş arar.
  • Yüksek performans: Dengesiz yüklerde etkilidir.

Golang'da, bu planlayıcıda (scheduler) goroutine'leri işletim sistemi iş parçacıklarına (M) dağıtmak için kullanılır. Bir M, mevcut işini (P üzerindeki goroutine paketleri) tamamladığında, diğer P'lerin yerel kuyruklarından goroutine'leri arar.

// Work stealing kavramını gösteren psödokod
package main

import "fmt"
import "sync"
import "time"

type Task struct {
	id int
}

// Görev kuyruğu simülasyonu
type TaskQueue struct {
	tasks []Task
	mu    sync.Mutex
}

func (q *TaskQueue) AddTask(task Task) {
	q.mu.Lock()
	defer q.mu.Unlock()
	q.tasks = append(q.tasks, task)
}

func (q *TaskQueue) GetLocalTask() (Task, bool) {
	q.mu.Lock()
	defer q.mu.Unlock()
	if len(q.tasks) == 0 {
		return Task{}, false
	}
	task := q.tasks[0]
	q.tasks = q.tasks[1:]
	return task, true
}

// Başka bir kuyruktan "çalmak" için girişim
func (q *TaskQueue) StealTask() (Task, bool) {
	q.mu.Lock()
	defer q.mu.Unlock()
	if len(q.tasks) < 2 { // Az görev varsa çalmıyoruz
		return Task{}, false
	}
	// Ortadan veya sondan çalmak, yerel çekişle çakışmayı önlemek için
	index := len(q.tasks) / 2
	task := q.tasks[index]
	q.tasks = append(q.tasks[:index], q.tasks[index+1:]...)
	return task, true
}

// İşçi simülasyonu
func worker(id int, localQueue *TaskQueue, otherQueues []*TaskQueue, wg *sync.WaitGroup) {
	defer wg.Done()

	for {
		// Yerel kuyruktan görev almaya çalışma
		task, ok := localQueue.GetLocalTask()
		if ok {
			fmt.Printf("İşçi %d, görev %d'yi yerel olarak yapıyor\n", id, task.id)
			time.Sleep(100 * time.Millisecond) // İşleme simülasyonu
			continue
		}

		// Eğer yerel kuyruk boşsa, çalmak için dene
		stolen := false
		for _, queue := range otherQueues {
			if queue == localQueue {
				continue // Kendinden çalmıyoruz
			}
			task, ok := queue.StealTask()
			if ok {
				fmt.Printf("İşçi %d, görev %d'yi çaldı\n", id, task.id)
				time.Sleep(100 * time.Millisecond) // İşleme simülasyonu
				stolen = true
				break // Başarılı çalmadan çık
			}
		}

		if !stolen {
			// Çalınacak görev kalmadıysa, pasif kalabilir veya durabilir
			// Gerçek bir planlayıcıda daha karmaşık sonlandırma mekanizmaları olur
			// Demo amaçlı, belli bir süre sonra çıkıyoruz
			fmt.Printf("İşçi %d pasif durumda, bekliyor...\n", id)
			time.Sleep(50 * time.Millisecond)
			// Gerçek senaryoda burada sonlandırma veya park mekanizması olur
			// return // Demo amaçlı çıkış izni veriyoruz
			break // Basitleştirilmiş simülasyon
		}
	}
}

func main() {
	numWorkers := 4
	numTasks := 20
	taskQueues := make([]*TaskQueue, numWorkers)
	for i := range taskQueues {
		taskQueues[i] = &TaskQueue{}
	}

	// Görevleri dengesiz dağıt, work stealing'i göstermek için
	for i := 0; i < numTasks; i++ {
		queueIndex := i % 2 // İlk iki işçiye daha fazla görev
		taskQueues[queueIndex].AddTask(Task{id: i})
	}

	var wg sync.WaitGroup
	for i := 0; i < numWorkers; i++ {
		wg.Add(1)
		// İşçinin "çalabilmesi" için tüm kuyruklara referanslar ver
		otherQueues := make([]*TaskQueue, 0, numWorkers-1)
		for j := range taskQueues {
			if i != j {
				otherQueues = append(otherQueues, taskQueues[j])
			}
		}
		go worker(i, taskQueues[i], otherQueues, &wg)
	}

	wg.Wait()
	fmt.Println("Tüm görevler tamamlandı")
}

```}}}}}]}},{