Tải bản đầy đủ (.docx) (19 trang)

Hãy biên dịch, chạy thử, bỏ hàm sleep() ở dòng 17, hoặc tăng giá trị đối số sleep() và giải thích kết quả chạy cho từng tình huống

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (729.1 KB, 19 trang )

1

TRƯỜ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, 2021-2022

Lab 4
Nhóm: 02 Tổ: 01
Thành Viên Nhóm: (SV tự chọn nhóm, tối đa 3 SV)
1:

Nguyễn Quốc Anh (MSSV: 52100871)

2:

Cao Hoàng Anh (MSSV: 52100917)

3:

Lục Minh Hiếu (MSSV: 52100889)

0

0


2

Mục lục


A. PHẦN THỰC HÀNH .................................................................................................

3

Ví Dụ 1:.................................................................................................................

3

Ví dụ 2: ..................................................................................................................

3

Ví dụ 3: ..................................................................................................................

4

Ví dụ 4: tổng hợp các ví dụ đã nêu. ......................................................................

5

B. PHẦN BÀI TẬP..........................................................................................................

7

BÀI 1:....................................................................................................................

7

BÀI 2:....................................................................................................................


8

BÀI 3:....................................................................................................................

9

BÀI 4:.................................................................................................................. 11
BÀI 5:.................................................................................................................. 13
BÀI 6:.................................................................................................................. 14
KẾT LUẬN.................................................................................................................... 18
KẾT QUẢ LÀM VIỆC CÁC THÀNH VIÊN TRONG NHÓM ................................... 19

0

0


3

A. PHẦN THỰC HÀNH
Ví Dụ 1:
Hãy biên dịch, chạy thử, bỏ hàm sleep() ở dòng 17, hoặc tăng giá
trị đối số sleep() và giải thích kết quả chạy cho từng tình huống.

A: Code Chương Trình
#include
#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);

B: Kết Quả Demo

Giải thích: Hàm sleep() trong sử dụng để dừng thực thi luồng hiện tại trong số giây
truyền vào. Ở trên sử dụng sleep(3) thì sau 3s sẽ kết thúc, nếu tang số giây lên thì sẽ
kết thúc lâu hơn.

Ví dụ 2:

A: Code Chương Trình
#include
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
struct arr{
int n;

int a[10];
};
void* thr1(void* ar){

0

0


4
int count;
struct arr *ap=(struct arr*) ar;
for(count=0;count<ap->n; count++) {
printf("%d\t",ap->a[count]);
}
printf("\n");

}
int main(int argc, char* argv[]){
struct arr ar;
ar.n=5;
int i;
for(i=0;iar.a[i]=i+1;
}
pthread_t tid;
pthread_create(&tid,NULL,&thr1,&ar);
sleep(2);
return 0;


}

B: Kết Quả Demo
Ví dụ 3:

A: Code Chương Trình
#include

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.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++) {
if(pthread_join(tid[i],(void**) pstatus)>0) {
printf("pthread_join for thread %d failure\n", (int)tid[i]);
}
printf("pthread_waited of %d OK, return code: %d\n", (int)tid[i],
status); sleep(1);

}
sleep(1);
return 0;
}

0

0


5

B: Kết Quả Demo:

Ví dụ 4: tổng hợp các ví dụ đã nêu.

A: Code Chương Trình
#include
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
struct arr{
int n;
int a[10];
};
struct file {
struct arr ar;
char* filename;
};

static int sum =0;
void* thr1(void* ar){
struct arr *ap = (struct arr*) ar;
ap->n=3;
int i=0;
for(i=0;i<ap->n;i++) {
ap->a[i] = i+1;
}
}
void* thr2(void* ar){
struct arr *ap = (struct arr*) ar;
int i, s=0;
for(i=0;i<ap->n;i++) {
s=s + ap->a[i];
}
sum=s;
}
void* thr3 (void* ar){
struct file *fi = (struct file*) ar;
FILE *out; int count;
out = fopen(fi->filename,"wb");

0

0


6
fprintf(out,"number element or 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);
printf("tong : %d\n",sum);
fclose(out);

}
int main (int argc,char * argv[]){
int i;
pthread_t tid[3];
struct arr ar;
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_join(tid[1], NULL)==0) {
struct file arf;
arf.ar=ar;
arf.filename=argv[1];
pthread_create(&tid[2],NULL,thr3,(void*) &arf);
}
}
sleep(2);
return 0;
}

B: Kết Quả Demo:


0

0


7

B. PHẦN BÀI TẬP
BÀI 1:
Viết chương trình đa luồng tính toán các giá trị thống kê khác nhau
từ một danh sách các số được truyền vào thông qua đối số của dịng
lệnh. Chương trình sau đó sẽ tạo ba tiểu trình tính tốn riêng biệt. Một
tiểu trình sẽ xác định trung bình cộng của các số, tiểu trình thứ hai sẽ
xác định giá trị lớn nhất và tiểu trình thứ ba sẽ xác định giá trị nhỏ nhất.

A: Code Chương Trình:
#include
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
struct arr{
int n;
int a[10];
};
static int average = 0;
static int max = 0;
static int min = 0;
void* thr1(void* ar){

struct arr *ap = (struct arr*) ar; // Ép kiểu về arr
int i=0, average_temp = 0;
for(i=0;i<ap->n;i++) {
average_temp = average_temp + ap->a[i] ;
}
average_temp = average_temp / ap->n;
average = average_temp;
}
void* thr2(void* ar){
struct arr *ap = (struct arr*) ar; // Ép kiểu về arr
int i, max_temp;
max_temp = ap->a[0];
for(i=1;i<ap->n;i++) {
if (max_temp < ap->a[i]) {
max_temp = ap->a[i];
}
}
max = max_temp;
}
void* thr3 (void* ar){
struct arr *ap = (struct arr*) ar; // Ép kiểu về arr
int i, min_temp;
min_temp = ap->a[0];
for(i=1;i<ap->n;i++) {
if (min_temp > ap->a[i]) {
min_temp = ap->a[i];
}
}
min = min_temp;
}

int main (int argc,char * argv[]){

0

0


8

}

int i;
pthread_t tid[3]; // Tạo các thread id
struct arr ar; // Tạo ar với struct arr
ar.n = argc - 1;
for (i=1;iar.a[i-1] = atoi(argv[i]); // Ép kiểu số
}
pthread_create(&tid[0], NULL, thr1, (void*) &ar); // Tạo
thr1 pthread_create(&tid[1], NULL, thr2, (void*) &ar); //
Tạo thr2 pthread_create(&tid[2], NULL, thr3, (void*)
&ar); // Tạo thr3 pthread_join(tid[0], NULL); // Đợi thr1
xong pthread_join(tid[1], NULL); // Đợi thr2 xong
pthread_join(tid[2], NULL); // Đợi thr3 xong
printf("Gia tri trung binh: %d\n", average);
printf("Gia tri lon nhat: %d\n", max);
printf("Gia tri nho nhat: %d\n", min);
return 0;

B: Kết Quả Demo:


BÀI 2:
Viết chương trình đa luồng để xuất ra số nguyên tố. Người dùng
chạy chương trình và nhập vào một số ngun thơng qua đối số tại dịng
lệnh. Chương trình sau đó sẽ tạo ra một tiến trình riêng biệt xuất ra tất cả
các số nguyên tố nhỏ hơn hoặc bằng số được nhập bởi người dùng.

A: Code Chương Trình:
#include
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
// Hàm ktr số nguyên tố
int check_prime(int num) {
int i;
for (i = 2; i*i <= num; i++) {
if (num % i == 0) {
return 0;
}
}
return 1;
}

0

0


9

void* thr1(void* ar){
int n = *((int *)ar); // Ép kiểu về int
int i;
if (n < 2) {

}

} else if (n == 2)
{ printf("2\n");
} else
{ printf("2"
);
for ( i = 3; i <= n; i+=2) { if
(check_prime(i) == 1){
printf(" %d", i);
}
}
printf("\n");
}

int main (int argc,char * argv[]){
pthread_t tid;
int n = atoi(argv[1]);
pthread_create(&tid, NULL, thr1, (void*) &n); // Tạo
thr1 pthread_join(tid, NULL); // Đợi thr1 xong
printf("Done\n");
return 0;
}

B: Kết Quả Demo:


BÀI 3:

Chỉnh sửa lại bài 1 sao cho thay vì xuất kết quả ra màn hình thì kết quả
sẽ được ghi vào tập tin result.txt ở cùng thư mục với chương trình chạy.

A: Code Chương Trình:
#include
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

0

0


10
struct arr{
int n;
int a[10];
};
struct file {
struct arr ar;
char* filename;
};
static int average = 0;
static int max = 0;
static int min = 0;

void* thr1(void* ar){
struct arr *ap = (struct arr*) ar; //Ép kiểu
int i=0, average_temp = 0;
for(i=0;i<ap->n;i++) {
average_temp = average_temp + ap->a[i] ;
}
average_temp = average_temp / ap->n;
average = average_temp;
}
void* thr2(void* ar){
struct arr *ap = (struct arr*) ar; //Ép kiểu
int i, max_temp;
max_temp = ap->a[0];
for(i=1;i<ap->n;i++) {
if (max_temp < ap->a[i]) {
max_temp = ap->a[i];
}
}
max = max_temp;

}
void* thr3 (void* ar){
struct arr *ap = (struct arr*) ar; //Ép kiểu
int i, min_temp;
min_temp = ap->a[0];
for(i=1;i<ap->n;i++) {
if (min_temp > ap->a[i]) {
min_temp = ap->a[i];
}
}

min = min_temp;

}
void* thr4 (void* ar) {
FILE *out;
out = fopen("result.txt","wb");

fprintf(out, "Gia tri trung binh: %d\n", average);

fprintf(out, "Gia tri lon nhat: %d\n", max);
fprintf(out, "Gia tri nho nhat: %d\n", min);
fclose(out);

}
int main (int argc,char * argv[]){

0

0


11
int i;
pthread_t tid[4];
struct arr ar;
ar.n = argc - 1;
for (i=1;iar.a[i-1] = atoi(argv[i]);
}
pthread_create(&tid[0], NULL, thr1, (void*) &ar); // Tạo thr1

pthread_create(&tid[1], NULL, thr2, (void*) &ar); // Tạo thr2
pthread_create(&tid[2], NULL, thr3, (void*) &ar); // Tạo thr3

pthread_join(tid[0], NULL); // Đợi thr1
pthread_join(tid[1], NULL); // Đợi thr2
pthread_join(tid[2], NULL); // Đợi thr3
// Sau khi đợi xong rồi ghi ra file với thr4
pthread_create(&tid[3], NULL, thr4, (void*) &tid[3]);
pthread_join(tid[3], NULL);
}

return 0;

B: Kết Quả Demo:

BÀI 4:
Viết chương trình để sao chép dữ liệu từ file nguồn vào file đích.
Với tên file nguồn và file đích là đối số đầu vào. Đếm số kí tự đã sao
chép. Giả sử chương trình chỉ chạy trên tập tin text.

A: Code Chương Trình:
#include
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
static long all_char;
struct file {
char* source_file;
char* target_file;

};

0

0


12
void* thr1(void* ar){
struct file *ap = (struct file*) ar; // Ép kiểu
FILE *fi;
fi = fopen(ap->source_file,"r");
FILE *fo;
fo = fopen(ap->target_file,"wb");

}

int dem=0;
char c;
while(c != EOF) {
c = fgetc(fi); // get char từ file input
if (c != EOF) {
fputc(c, fo); // put char qua file output
}
dem++; // Đếm ký tự
}
all_char = dem;

int main (int argc,char * argv[]){
pthread_t tid;

struct file f;
f.source_file = argv[1];
f.target_file = argv[2];
pthread_create(&tid, NULL, thr1, (void*) &f); // tạo
thr1 pthread_join(tid, NULL); // Đợi thr1
printf("Da sao chep thanh cong %ld ki tu.\n",
all_char); return 0;
}

B: Kết Quả Demo:

0

0


13

BÀI 5:
Viết chương trình tạo ra 3 thread thực hiện các công việc sau:

Thread thứ nhất nhận đối số truyền từ môi trường (argv[1]), kiểm
tra nếu số này lớn 0, tính giai thừa của số này (có thể sử dụng struct hoặc biến
toàn cục).

Thread thứ hai chờ thread thứ nhất hồn tất, thực hiện việc tính tổng
các số chẳn từ nhỏ hơn kết quả giai thừa thread thứ nhất tính được.


Thread thứ ba chờ thread thứ 2 hoàn tất, ghi kết quả vào file là đối số thứ


2 từ biến mơi trường (argv[2]). Nội dung ghi vào gồm: dịng thứ
nhất lưu giá trị của argv[1]; dòng thứ 2 lưu kết quả của giai thừa;
dòng thứ 3 lưu tổng các số chẵn nhỏ hơn giai thừa.

A:

Code Chương Trình:
#include
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
static long factorial = 1;
static int sum_even = 0;
static int n = 0;
void* thr1(void* ar){
int i;
long factorial_temp = 1;
for (i = 1; i <= n; i++) {
factorial_temp *= i;
}
factorial = factorial_temp;
}
void* thr2(void* ar){
int i;
int sum_temp = 0;
for(i = 2; i<=factorial; i+=2) {
sum_temp += i;
}

sum_even = sum_temp;
}
void* thr3 (void* ar) {
FILE *out;
out = fopen((char *) ar,"wb");
fprintf(out, "n = %d\n", n);
fprintf(out, "%d! = %ld\n", n, factorial);
fprintf(out, "sum = %d\n", sum_even);

0

0


14
fclose(out);
}
int main (int argc,char * argv[]){
int i;
pthread_t tid[3];
n = atoi(argv[1]); // Ép kiểu
pthread_create(&tid[0], NULL, thr1, (void*) &tid[0]); // Tạo
thr1 pthread_join(tid[0], NULL); // Đợi thr1
pthread_create(&tid[1], NULL, thr2, (void*) &tid[1]); // Tạo
thr2 pthread_join(tid[1], NULL); // Đợi thr2
pthread_create(&tid[2], NULL, thr3, argv[2]); // Tạo
thr3 pthread_join(tid[2], NULL); // Đợi thr3

}


printf("Da tao ra tap tin %s\n", argv[2]);
return 0;

B: Kết Quả Demo:

BÀI 6:
Cho một tập tin có cấu trúc sau:


Dòng đầu tiên chứa số phần tử mảng



Dòng còn lại chứa các phần tử là số nguyên
Viết chương trình gồm các thread thực hiện các cơng việc sau:



Thread thứ nhất đọc file đầu vào là đối số thứ nhất từ biến mơi trường



Thread thứ hai tính tổng các số nguyên tố trong mảng



Thread thứ ba tính sắp xếp mảng tăng dần

0


0


15


Thread thứ tư thực hiện việc ghi file result. Nội dung file đầu vào
và đầu ra như sau:

A:

Code Chương Trình:
#include
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

/

Mảng các số nguyên tố struct prime_array {
int length;
};

int prime_arr[100];
int sum;

/
Xử dụng biến toàn cục để share dữ liệu giữa các thread static struct prime_array parr,
copy_parr;

static int n = 0;
static int arr[100];

/

Kiểm tra số nguyên tố
int check_prime(int num) {
int i;
for (i = 2; i*i <= num; i++) {
if (num % i == 0) {
return 0;
}
}
return 1;
}
void* thr1 (void* ar) {
int i;
FILE *fi;
fi = fopen("input.txt", "r");
fscanf(fi, "%d\n", &n);
for (i = 0; i < n; i++) {
fscanf(fi,"%d", &arr[i]);
}
fclose(fi);
}
void* thr2 (void* arg) {
int i;
int length = 0;
int sum = 0;
for (i = 0; i < n; i++) {

if (check_prime(arr[i]) == 1) {
parr.prime_arr[length] = arr[i];
sum += arr[i];
length++;
}
}

0

0


16

}

/

parr.length = length;
parr.sum = sum;

void* thr3 (void* arg) {
int min_idx = 0;
int i, j;
int temp;
Copy qua copy_parr để lưu lại trc khi sắp xếp copy_parr.length = parr.length;
for (i = 0; i < parr.length; i++)
{ copy_parr.prime_arr[i] = parr.prime_arr[i];

}


/

Sắp xếp với thuật toán selection sort
for (i = 0; i < parr.length - 1; i++) {
min_idx = i;
for (j = i; j < parr.length; j++) {
if (parr.prime_arr[min_idx] > parr.prime_arr[j]) {
min_idx = j;
}
}
// Swap
temp = parr.prime_arr[min_idx];
parr.prime_arr[min_idx] = parr.prime_arr[i];
parr.prime_arr[i] = temp;
}

}
void* thr4 (void* ar) {
int i;
FILE *fo;
fo = fopen("result.txt", "wb");
//ý1
fprintf(fo, "So phan tu trong mang: %d\n", n);
for (i = 0; i < n - 1; i++) {
fprintf(fo,"%d ", arr[i]);
}
fprintf(fo,"%d\n", arr[n-1]);
//ý2
fprintf(fo, "Mang so nguyen to:\n");

for (i = 0; i < copy_parr.length - 1; i++) {
fprintf(fo, "%d ", copy_parr.prime_arr[i]);
}

fprintf(fo, "%d\n", copy_parr.prime_arr[copy_parr.length - 1]);

//ý3
fprintf(fo, "Tong cac so nguyen to: %d\n", parr.sum);

}

//ý4
fprintf(fo, "Mang cac so nguyen to da duoc sap xep\
n"); for (i = 0; i < parr.length - 1; i++) {
fprintf(fo, "%d ", parr.prime_arr[i]);
}
fprintf(fo, "%d\n", parr.prime_arr[parr.length - 1]);
fclose(fo);

0

0


17
int main (int argc,char * argv[]){
pthread_t tid[4];

pthread_create(&tid[0], NULL, thr1, (void*) &tid[0]); // Tạo thr1


pthread_join(tid[0], NULL); // Đợi thr1

pthread_create(&tid[1], NULL, thr2, (void*) &tid[1]); // Tạo thr2

pthread_join(tid[1], NULL); // Đợi thr2

pthread_create(&tid[2], NULL, thr3, (void*) &tid[2]); // Tạo thr3

pthread_join(tid[2], NULL); // Đợi thr3

pthread_create(&tid[3], NULL, thr4, (void*) &tid[3]); // Tạo thr4

}

pthread_join(tid[3], NULL); // Đợi thr4
return 0;

B: Kết Quả Demo:

0

0


18

KẾT LUẬN
Sau khi học và hoàn thành phần lab 4 nhóm thu được kết sau:

-


Hiểu sơ bộ về Thread và Concurrency.
Biết được cách tạo và kết thúc Thread
Nắm cơ bản các cách thao tác trên tập tin
Chú ý bài làm giống nhau sẽ bị trừ điểm.

0

0


19

KẾT QUẢ LÀM VIỆC CÁC THÀNH VIÊN TRONG NHÓM
HỌ TÊN SV

MÃ SV

VAI
TRỊ

CƠNG VIỆC ĐƯỢC PHÂN CƠNG

Nguyễn Quốc Anh

52100871

TN

BT3, BT4, BT5


100%

Cao Hoàng Anh

52100917

TV

Demo code BT, BT1, BT2

100%

Lục Minh Hiếu

52100889 TV

Word, demo code VD, BT6

100%

CHÚ THÍCH:
TN: TRƯỞNG NHĨM
TV: THÀNH VIÊN
HT: MỨC ĐỘ HỒN THÀNH CƠNG VIỆC ĐƯỢC GIAO

0

0


HT



×