ĐỒNG BỘ

Bài toán tiến trình Sản xuất – Tiêu thụ

Chương trình C minh họa bài toán bằng giải pháp Semaphore

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

#define MaxItems 5      // Số items tối đa một tiến trình Producer có thể tạo hoặc một tiến trình Consumer có thể dùng
#define BufferSize 3    // Kích thước bộ đệm

sem_t empty;    //Biến kiểm soát số ô nhớ trống
sem_t full;     //Biến kiểm soát số ô nhớ đầy
int in = 0;     //Biến hoạt động của tiến trình Producer
int out = 0;    //Biến hoạt động của tiến trình Consumer
int buffer[BufferSize]; //Mảng ô nhớ
pthread_mutex_t mutex;  //Khóa kiểm soát tranh chấp

//Tiến trình Sản xuất (Producer)
void *producer(void *prod)
{   
    int i, item;
    for(i = 0; i < MaxItems; i++) {
        item = rand(); // Tạo ngẫu nhiên 1 mục
        sem_wait(&empty);   //Giảm số ô nhớ trống
        pthread_mutex_lock(&mutex); //Báo hiệu vào vùng tranh chấp
        buffer[in] = item;  //thêm mục vào ô nhớ
        printf("Tiến trình Producer %d: thêm mục %d vào ô nhớ %d\n", *((int *)prod),buffer[in],in);
        in = (in+1)%BufferSize; //Trỏ đến ô nhớ kế tiếp
        pthread_mutex_unlock(&mutex);   //Ra khỏi vùng tranh chấp
        sem_post(&full);    //Tăng số ô nhớ đầy
    }
}

//Tiến trình tiêu thụ (Consumer)
void *consumer(void *cons)
{   
    int i;
    for(i = 0; i < MaxItems; i++) {
        sem_wait(&full);    //Giảm số ô nhớ đầy
        pthread_mutex_lock(&mutex); //Báo hiệu vào vùng tranh chấp
        int item = buffer[out]; //Lấy thông tin từ ô nhớ
        printf("Tiến trình Consumer %d: lấy mục %d ra khỏi ô nhớ %d\n",*((int *)cons),item, out);
        out = (out+1)%BufferSize;   //Trỏ đến ô nhớ kế tiếp
        pthread_mutex_unlock(&mutex);   //Ra khỏi vùng tranh chấp
        sem_post(&empty);   //Tăng số ô nhớ trống
    }
}


int main()
{   

    pthread_t pro[5],con[5];
    pthread_mutex_init(&mutex, NULL);
    sem_init(&empty,0,BufferSize);
    sem_init(&full,0,0);
    int i;

    int a[5] = {1,2,3,4,5};     //Số thứ tự của tiến trình Sản xuất, Tiêu thụ

    for(i = 0; i < 5; i++) {
        pthread_create(&pro[i], NULL, (void *)producer, (void *)&a[i]);
    }
    for(i = 0; i < 5; i++) {
        pthread_create(&con[i], NULL, (void *)consumer, (void *)&a[i]);
    }

    for(i = 0; i < 5; i++) {
        pthread_join(pro[i], NULL);
    }
    for(i = 0; i < 5; i++) {
        pthread_join(con[i], NULL);
    }

    pthread_mutex_destroy(&mutex);
    sem_destroy(&empty);
    sem_destroy(&full);

    return 0;
    
}

Kết quả biên dịch chương trình bằng GCC trên môi trường hệ điều hành CentOS

Lưu ý khi biên dịch phải liên kết thư viện tiểu trình: gcc tên_chương_trình.c –lpthread –o tên_file_chạy

Bài toán bữa ăn tối của các Triết gia

Chương trình C minh họa bài toán bằng giải pháp Semaphore

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<semaphore.h>
#include<unistd.h>

sem_t quyen;
sem_t dua[5];

void * trietgiaantoi(void *);
void an(int);
int main()
{
	int i,a[5];
	pthread_t tid[5];

	sem_init(&quyen,0,4); //khởi tạo semaphore quyen

	for(i=0;i<5;i++)
		sem_init(&dua[i],0,1); //khởi tạo semaphore dua

	for(i=0;i<5;i++){
		a[i]=i+1;
		pthread_create(&tid[i],NULL,trietgiaantoi,(void *)&a[i]); //Tạo tiểu trình
	}
	for(i=0;i<5;i++)
		pthread_join(tid[i],NULL);  //Nối tiểu trình
}

void * trietgiaantoi(void * num)
{
	int trietgia=*(int *)num;

	sem_wait(&quyen);   //Yêu cầu quyền cầm đủ đũa
	printf("\nTriết gia %d có quyền cầm một đôi đũa",trietgia);
	sem_wait(&dua[trietgia]);   //Có chiếc đũa thứ nhất
	sem_wait(&dua[(trietgia+1)%5]); //Có chiếc đũa thứ hai

	an(trietgia);   //Ăn
	sleep(2);   //Dừng tiến trình 2 giây
	printf("\nTriết gia %d ăn xong",trietgia);

	sem_post(&dua[(trietgia+1)%5]); //Trả chiếc đũa thứ hai
	sem_post(&dua[trietgia]);   //Trả chiếc đũa thứ nhất
	sem_post(&quyen);   //Trao quyền lại cho triết gia khác
}

void an(int trietgia)
{
	printf("\nTriết gia %d đang ăn",trietgia);
}

Kết quả biên dịch chương trình bằng GCC trên môi trường hệ điều hành CentOS

Last updated