PH N BÀI T PẦẬBÀI 1: Viết chương trình tạo ba luồng thực hiện các tác vụ sau:- Luồng đầu tiên lấy đối số từ môi trường argv [1], kiểm tra xem số đó có bằng0 hay không, tính giai thừa của
Trang 1TRƯỜNG ĐẠI HỌC TÔN ĐỨC THẮNG KHOA CÔNG NGHỆ THÔNG TIN
BÁO CÁO BÀI TẬP NMHĐH
HK2, 2022-2023 Lab 5
Trang 2Mục lục
Contents
A PHẦN THỰC HÀNH 3
V Í D Ụ 1: 3
A: Code Chương Trình 3
B: Kết Quả Demo 4
V Í D Ụ 2: 4
A: Code Chương Trình 4
B: Kết Quả Demo 5
V Í D Ụ 3: 5
A: Code Chương Trình 5
B: Kết Quả Demo 7
V Í D Ụ 4: 7
A: Code Chương Trình 7
B: Kết quả Demo 10
B PHẦN BÀI TẬP 10
BÀI 1: 10
A: Code Chương Trình: 10
B: Kết Quả Demo: 13
BÀI 2: 13
A: C ODE HƯƠNG RÌNH C T : 14
B: Kết Quả Demo: 17
C KẾT LUẬN 18
Trang 3A PH N TH C HÀNH Ầ Ự
Ví D 1:ụ
A: Code Chươ ng Trình
// vd1.c
#include <pthread.h>
#include <stdio.h>
void* thr1(void* ar)
{
printf("This is thread %d\n", *((int*)ar));
sleep(2);
}
int main(int argc, char* argv[])
{
int i;
int num = atoi(argv[1]);
pthread_t tid[num];
for(i = 0; i < num; i++)
{
pthread_create(&tid[i], NULL, thr1, (void*) &tid[i]); }
sleep(3);
return 0;
}
Trang 4B: K t Qu Demoế ả
Ví D 2:ụ
A: Code Chươ ng Trình
//vd2.c
#include <pthread.h>
#include <stdio.h>
void* thr1(void* ar)
{
int count;
printf("This is thread %d\n", *((int*)ar));
sleep(2);
}
int main(int argc, char* argv[])
{
int i;
pthread_t tid[3];
int status, *pstatus = &status;
for(i = 0; i < 3; i++)
{
pthread_create(&tid[i], NULL, thr1, (void*) &tid[i]); }
for(i = 0; i < 3; i++)
Trang 5{
if(pthread_join(tid[i],(void**) pstatus) > 0)
{
printf("pthread_jold for thread %d fatlure\n", (int)tid[i]); return 0;
}
printf("pthread_waited of %d OK, return code: %d\n", (int)tid[i], status);
sleep(1);
}
sleep(1);
return 0;
}
B: K t Qu Demoế ả
Ví D 3:ụ
A: Code Chươ ng Trình
//vd3.c
#include <pthread.h>
#include <stdio.h>
void* thr1(void* ar)
{
int count;
printf("This is thread %d\n", *((int*)ar));
Trang 6sleep(2);
}
int main(int argc, char* argv[])
{
int i;
pthread_t tid[3];
int status, *pstatus = &status;
for(i = 0; i < 3; i++)
{
pthread_create(&tid[i], NULL, thr1, (void*) &tid[i]);
}
for(i = 0; i < 3; i++)
{
if(pthread_join(tid[i], (void**) pstatus) > 0)
{
printf("pthread_joid for thread %d failure\n", (int)tid[i]); return 0;
}
printf("pthread_waited of %d OK, return code: %d\n", (int)tid[i], status);
sleep(1);
}
sleep(1);
return 0;
}
Trang 7B: K t Qu Demoế ả
Ví D 4:ụ
A: Code Chươ ng Trình
//vd4.c
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
struct arr
{
int n;
int a[10];
};
struct file
{
char *filename;
};
static int sum = 0;
{
Trang 8ap->n = 3;
int i;
for (i = 0; i < ap->n; i++)
{
ap->a[i] = i + 1;
}
}
{
int i, s = 0;
for (i = 0; i < ap->n; i++)
{
s = s + ap->a[i];
}
sum = s;
}
{
int count;
out = fopen(fi->filename, "w");
if (out != NULL)
{
fprintf(out, "number element of array: %d\n", fi->ar.n); for (count = 0; count < fi->ar.n; count++)
{
fprintf(out, "%d\t", fi->ar.a[count]);
}
fprintf(out, "\n");
fprintf(out, "sum = %d\n", sum);
fclose(out);
}
else
Trang 9{
printf("Error opening file.\n");
}
}
{
int i;
pthread_t tid[3];
int status, *pstatus = &status;
pthread_create(&tid[0], NULL, thr1, (void *)&ar);
sleep(1);
if (pthread_join(tid[0], (void **)pstatus) == 0)
{
pthread_create(&tid[1], NULL, thr2, (void *)&ar);
if (pthread_create(&tid[1], NULL, thr2, (void *)&ar) == 0) {
struct file arf;
arf.ar = ar;
arf.filename = argv[1];
pthread_create(&tid[2], NULL, thr3, (void *)&arf); }
}
sleep(2);
return 0;
}
Trang 10B: K tế qu Demoả
B PH N BÀI T P Ầ Ậ
BÀI 1:
Viết chương trình tạo ba luồng thực hiện các tác vụ sau:
- Luồng đầu tiên lấy đối số từ môi trường (argv [1]), kiểm tra xem số đó có bằng
0 hay không, tính giai thừa của số này (có thể sử dụng biến struct hoặc biến toàn cục)
- Luồng thứ 2 chờ luồng thứ nhất hoàn thành, thực hiện tính toán số từ nhỏ hơn kết quả của hệ số giai thừa thứ nhất đã tính
- Thread thứ 3 chờ thread thứ 2 hoàn thành, ghi kết quả vào file là đối số thứ 2 từ biến môi trường (argv [2]) Nội dung của bản ghi bao gồm: dòng đầu tiên lưu giá trị của argv [1]; Dòng thứ hai lưu kết quả của giai thừa; Dòng thứ ba lưu tổng các số nhỏ hơn giai thừa
Đầu ra của tệp res1 như sau:
N = 4
4! = 24
Sum = 156
A: Code Chươ ng Trình:
//bai1.c
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Trang 11struct ThreadArgs {
int number;
int factorial;
int wordCount;
char* outputFileName;
};
void *calculateFactorial(void *args) {
struct ThreadArgs *data = (struct ThreadArgs *)args; int n = data->number;
int fact = 1;
for (int i = 1; i <= n; i++) {
fact *= i;
}
data->factorial = fact;
pthread_exit(NULL);
}
void *calculateWordCount(void *args) {
struct ThreadArgs *data = (struct ThreadArgs *)args; while (data->factorial == 0) {
// Chờ cho đến khi luồng tính giai thừa hoàn thành }
char factStr[20];
snprintf(factStr, sizeof(factStr), "%d", data->factorial); int count = 0;
char *token = strtok(factStr, " ");
while (token != NULL) {
count++;
token = strtok(NULL, " ");
}
data->wordCount = count;
Trang 12pthread_exit(NULL);
}
void *writeToFile(void *args) {
struct ThreadArgs *data = (struct ThreadArgs *)args; while (data->wordCount == 0) {
// Chờ cho đến khi luồng tính số từ hoàn thành
}
FILE *file = fopen(data->outputFileName, "w");
if (file != NULL) {
fprintf(file, "N = %d\n", data->number);
fprintf(file, "%d! = %d\n", data->number, data->factorial); fprintf(file, "Sum = %d\n", data->wordCount);
fclose(file);
} else {
printf("Lỗi khi mở tập tin.\n");
}
pthread_exit(NULL);
}
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Sử dụng: %s <số> <tập_tin_kết_quả>\n", argv[0]); return 1;
}
int number = atoi(argv[1]);
struct ThreadArgs data;
data.number = number;
data.factorial = 0;
data.wordCount = 0;
data.outputFileName = argv[2]; // Lưu tên tập tin kết quả pthread_t threads[3];
Trang 13pthread_create(&threads[0], NULL, calculateFactorial, &data);
pthread_create(&threads[1], NULL, calculateWordCount, &data);
pthread_create(&threads[2], NULL, writeToFile, &data);
pthread_join(threads[0], NULL);
pthread_join(threads[1], NULL);
pthread_join(threads[2], NULL);
return 0;
}
B: K t Qu Demo:ế ả
BÀI : 2
Đối với một tệp có cấu trúc sau:
- Dòng đầu tiên ghi số phần tử của mảng
- Các dòng còn lại chứa phần tử nguyên
Viết chương trình các luồng thực hiện các nhiệm vụ sau:
- Lần đọc file đầu vào đầu tiên là đối số đầu tiên từ biến môi trường
- Luồng thứ hai đếm tổng các số nguyên tố trong mảng
- Chuỗi thứ ba sắp xếp mảng tăng
- Luồng thứ tư thực hiện việc ghi file kết quả.
Nội dung tập tin đầu vào và đầu ra như sau:
Ví dụ: tệp đầu vào có định dạng sau
10
4
5
7
Trang 1411
9
20
13
2
3
Kết quả trong tệp kết quả trông như thế này: Size of array: 10
Value of elements: 4 5 7 8 11 9 20 13 2 3 Primes: 5 7 11 13 2 3
Sum of Primes: 41
Primes sorted from smallest to highest: 2 3 5 7 11 13
A: Code Chươ ng Trình:
//bai2.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define MAX_SIZE 100
int array[MAX_SIZE];
int primes[MAX_SIZE];
int size = 0;
int primeCount = 0;
int primeSum = 0;
// Đọc dữ liệu từ file input
void readInputFile(const char *fileName) { FILE *file = fopen(fileName, "r");
if (file == NULL) {
perror("Lỗi khi mở file");
exit(EXIT_FAILURE);
}
// Đọc số lượng phần tử mảng từ file fscanf(file, "%d", &size);
Trang 15// Đọc các phần tử mảng từ file
for (int i = 0; i < size; i++) {
fscanf(file, "%d", &array[i]);
}
fclose(file);
}
// Kiểm tra xem một số có phải số nguyên tố không int isPrime(int num) {
if (num <= 1) return 0;
for (int i = 2; i * i <= num; i++) {
if (num % i == 0) return 0;
}
return 1;
}
// Thread đếm số lượng số nguyên tố và tính tổng của chúng void *countPrimes(void *arg) {
for (int i = 0; i < size; i++) {
if (isPrime(array[i])) {
primes[primeCount++] = array[i];
primeSum += array[i];
}
}
return NULL;
}
// Hàm so sánh dùng trong việc sắp xếp mảng số nguyên tố int compare(const void *a, const void *b) {
return (*(int *)a - *(int *)b);
}
// Thread sắp xếp mảng số nguyên tố theo thứ tự tăng dần void *sortPrimes(void *arg) {
qsort(primes, primeCount, sizeof(int), compare);
Trang 16return NULL;
}
// Ghi kết quả vào file output
void *writeResultFile(void *arg) {
FILE *file = fopen("result.txt", "w");
if (file == NULL) {
perror("Error opening file");
exit(EXIT_FAILURE);
}
// Ghi thông tin về mảng vào file
fprintf(file, "Size of array: %d\n", size);
fprintf(file, "Value of elements: ");
for (int i = 0; i < size; i++) {
fprintf(file, "%d ", array[i]);
}
fprintf(file, "\nPrimes: ");
for (int i = 0; i < primeCount; i++) {
fprintf(file, "%d ", primes[i]);
}
fprintf(file, "\nSum of Primes: %d\n", primeSum); fprintf(file, "Primes sorted from smallest to highest: "); for (int i = 0; i < primeCount; i++) {
fprintf(file, "%d ", primes[i]);
}
fclose(file);
return NULL;
}
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("Sử dụng: %s <file_input>\n", argv[0]); return EXIT_FAILURE;
}
Trang 17// Đọc dữ liệu từ file input được truyền qua tham số readInputFile(argv[1]);
// Khởi tạo các thread
pthread_t threads[3];
pthread_create(&threads[0], NULL, countPrimes, NULL); pthread_create(&threads[1], NULL, sortPrimes, NULL); // Chờ các thread kết thúc
pthread_join(threads[0], NULL);
pthread_join(threads[1], NULL);
// Ghi kết quả ra file
writeResultFile(NULL);
return EXIT_SUCCESS;
}
B: K t Qu Demo:ế ả
Trang 18C K T LU N Ế Ậ
Sau khi học và hoàn thành phần lab 4 nhóm thu được kết sau:
1 Đồng thời và xử lý bất đồng bộ (Multithreading): Sử dụng các thread
để thực hiện các nhiệm vụ cùng một lúc có thể cải thiện hiệu suất của chương trình, đặc biệt khi có các tác vụ độc lập có thể thực hiện song song.
2 Sử dụng thư viện POSIX Threads (pthread.h): Quản lý các thread để thực hiện các tác vụ cùng một lúc Quen thuộc với việc tạo, chạy và kết thúc các thread.