ĐỒ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