This commit is contained in:
Tien
2019-11-17 15:06:20 +07:00
parent 2ffb7a19a4
commit d753ae2fdc
54 changed files with 899 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
all: main.o factorial.o readline.o
gcc main.o factorial.o readline.o -o myfactorial -lgmp
main.o: main.c factorial.h readline.h
gcc -c main.c
factorial.o: factorial.c factorial.h
gcc -c factorial.c
readline.o: readline.c readline.h
gcc -c readline.c
clean:
rm -f *.o myfactorial
+16
View File
@@ -0,0 +1,16 @@
#include "gmp.h"
#include "factorial.h"
#include <stdio.h>
#include <stdlib.h>
char *factorial(const int aNumber) {
int i;
mpz_t p;
mpz_init_set_ui(p, 1);
for (int i = 1; i <= aNumber; ++i) {
mpz_mul_ui(p, p, i);
}
char * ret = mpz_get_str(NULL, 10, p);
mpz_clear(p);
return ret;
}
+16
View File
@@ -0,0 +1,16 @@
#include "gmp.h"
#include "factorial.h"
#include <stdio.h>
#include <stdlib.h>
char *factorial(const int aNumber) {
int i;
mpz_t p;
mpz_init_set_ui(p, 1);
for (int i = 1; i <= aNumber; ++i) {
mpz_mul_ui(p, p, i);
}
char * ret = mpz_get_str(NULL, 10, p);
mpz_clear(p);
return ret;
}
+6
View File
@@ -0,0 +1,6 @@
#ifndef FACTORIAL_H
#define FACTORIAL_H
char *factorial(const int aNumber);
#endif
+28
View File
@@ -0,0 +1,28 @@
#include <stdio.h>
#include <stdlib.h>
#include "readline.h"
#include "factorial.h"
int main(int argc, char *argv[]) {
char *str = (char *) malloc(51);
int t = 0,
i = 0;
scanf("%d\n", &t);
while (i < t) {
if (read_line(str)) {
int a = atoi(str);
char *str = factorial(a);
if (t != NULL) {
puts(t);
free(t);
} else {
printf("Overflow!\n");
}
} else {
printf("%d\n", -1);
}
++i;
}
free(str);
return 0;
}
+17
View File
@@ -0,0 +1,17 @@
#include "readline.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
int read_line(char *str) {
fgets(str, 51, stdin);
fputs(str, stdout);
int i = 0;
while (str[i] != '\n') {
if (!isdigit(str[i])) {
return 0;
}
++i;
}
return 1;
}
+6
View File
@@ -0,0 +1,6 @@
#ifndef READ_LINE_H
#define READ_LINE_H
int read_line(char *str);
#endif
+9
View File
@@ -0,0 +1,9 @@
all: ex1.o ex2.o
gcc ex1.o -o ex1 -lgmp
gcc ex2.o -o ex2
ex1.o: ex1.c
gcc -c ex1.c
ex2.o: ex2.c
gcc -c ex2.c
clean:
rm -f *.o ex1 ex2
Binary file not shown.
BIN
View File
Binary file not shown.
+84
View File
@@ -0,0 +1,84 @@
#include <gmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#define FILE_NAME "numbers.txt"
#define MAX_SIZE 10
mpz_t array[MAX_SIZE];
int size = 0;
void readfile() {
FILE *file;
char str[80];
mpz_t temp;
mpz_init(temp);
file = fopen(FILE_NAME, "r");
if (file == NULL) {
perror("Can't open file!\n");
exit(1);
}
while (1) {
fgets(str, 80, file);
if (feof(file)) {
break;
}
if (mpz_set_str(temp, str, 10)) {
perror("Error! Not a number");
exit(1);
}
mpz_set(array[size++], temp);
}
mpz_clear(temp);
fclose(file);
}
void count(int n) {
int count = 0;
mpz_t temp;
mpz_init(temp);
for (int i = 0; i < size; ++i) {
mpz_mod_ui(temp, array[i], n);
if (!mpz_cmp_ui(temp, 0)) {
++count;
}
}
printf("Co %d so chia het cho %d.\n", count, n);
mpz_clear(temp);
}
int main() {
int child1_pid = 0,
child2_pid = 0,
child3_pid = 0,
parrent_pid = getpid();
readfile();
child1_pid = fork();
if (child1_pid < 0) {
perror("Error at 1st pork()!\n");
exit(1);
} else if (child1_pid == 0) {
count(2);
}
if (parrent_pid == getpid()) {
child2_pid = fork();
if (child2_pid < 0) {
perror("Error at 2nd pork()!\n");
exit(1);
} else if (child2_pid == 0) {
count(3);
}
}
if (parrent_pid == getpid()) {
child3_pid = fork();
if (child3_pid < 0) {
perror("Error at 3rd pork()!\n");
exit(1);
} else if (child3_pid == 0) {
count(5);
}
}
return 0;
}
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
+9
View File
@@ -0,0 +1,9 @@
12918237493729473291790579217597
4213412542666666666666665
321456765
4432524352352365
106235754869
11356243645879870
345943809680943809584352245
jweois
209345790jdsljflks
+8
View File
@@ -0,0 +1,8 @@
all: main.o ex1.o
gcc main.o ex1.o -o ex1 -lm
main.o: main.c ex1.h
gcc -c main.c
ex1.o: ex1.c ex1.h
gcc -c ex1.c
clean:
rm -f *.o ex1
+94
View File
@@ -0,0 +1,94 @@
#include "ex1.h"
/* Tim block trong dau tien co size thich hop */
blk *find_fit(unsigned int size)
{
blk *cur = head;
while (cur != NULL)
{
if (cur->is_free == 1 && cur->size >= size)
break;
cur = cur->next;
}
return cur;
}
void *aligned_malloc(unsigned int size, unsigned int align)
{
if (size == 0)
return NULL;
/* Kiem tra align la so mu cua 2 */
if (IS_POWER_OF_2(align) == 0)
return NULL;
/* Tong gia tri do lon cua block can xin */
unsigned int total_size = size + align - 1 + sizeof(blk) + sizeof(blk *);
/* Tim block trong thich hop (neu co) */
blk *blk_head = find_fit(total_size);
void *ret;
if (blk_head != NULL)
{
/* Gan gia tri "da duoc dung" */
blk_head->is_free = 0;
/* Tim vi tri tra ve thich hop */
ret = (void *)(ALIGN(blk_head + sizeof(blk) + sizeof(blk *), align));
/* Luu con tro den vi tri giu thong tin cua block */
*(blk **)((size_t)ret - sizeof(blk *)) = blk_head;
return ret;
}
void *block = sbrk(total_size);
if (block == (void *)-1)
return NULL;
/* Vi tri luu thong tin cua block */
blk_head = block;
blk_head->size = total_size;
blk_head->is_free = 0;
blk_head->next = NULL;
if (head == NULL)
head = blk_head;
if (tail != NULL)
tail->next = blk_head;
tail = blk_head;
/* Tim vi tri tra ve thich hop */
ret = (void *)(ALIGN(block + sizeof(blk) + sizeof(blk *), align));
/* Luu con tro den vi tri giu thong tin cua block */
*(blk **)((size_t)ret - sizeof(blk *)) = blk_head;
return ret;
}
/* Ham nay khong nhat thiet phai tra ve con tro (void *), tuy nhien em lam theo prototype de bai yeu cau */
void *aligned_free(void *ptr)
{
if (ptr == NULL)
return NULL;
/* Tro den vi tri luu thong tin cua block */
blk *blk_head = *((blk **)((size_t)ptr - sizeof(blk *)));
void *prg_brk = sbrk(0);
/* Neu block nam o sat diem break, (neu co thi block nay phai o tail) */
if ((size_t)blk_head + blk_head->size == (size_t)prg_brk)
{
if (head == tail)
{
head = NULL;
tail = NULL;
}
else
{
blk *tmp = head;
while (tmp != NULL)
{
if (tmp->next == tail)
{
tmp->next = NULL;
tail = tmp;
}
tmp = tmp->next;
}
}
sbrk(0 - (unsigned int)blk_head->size);
return NULL;
}
/* Neu khong giai phong duoc vung nho, danh dau block la "trong" */
blk_head->is_free = 1;
/* Tra ve con tro toi vi tri luu thong tin cua block (co the dung de debug) */
return (void *)blk_head;
}
+71
View File
@@ -0,0 +1,71 @@
#include "ex1.h"
memNode *findFree(size_t size)
{
memNode *cur = head;
while (cur != NULL) {
if (cur->isFree == 1 && cur->size >= size)
return cur;
cur = cur->next;
}
return NULL;
}
void *aligned_malloc(unsigned int size, unsigned int align)
{
if (size == 0)
return NULL;
if (ceil(log2((long)align)) != floor(log2((long)align)))
return NULL;
unsigned int total_size = size + align - 1 + sizeof(memNode);
memNode *header = findFree(total_size);
void *ret = NULL;
if (header != NULL) {
header->isFree = 0;
ret = (void *) (((size_t)header + sizeof(memNode) + align - 1) & ~((size_t) align - 1));
*((void **)((size_t)ret - sizeof(memNode))) = header;
return ret;
}
void *block = sbrk(total_size);
if (block == (void *) -1)
return NULL;
header = block;
header->size = total_size;
header->block = (size_t)block;
header->isFree = 0;
header->next = NULL;
if (head == NULL)
head = header;
if (tail != NULL)
tail->next = header;
tail = header;
ret = (void *) (((size_t)header + sizeof(memNode) + align - 1) & ~((size_t) align - 1));
*((void **)((size_t)ret - sizeof(memNode))) = header;
return ret;
}
void aligned_free(void *ptr)
{
if (ptr == NULL)
return;
memNode *header = (memNode *)((size_t)ptr - sizeof(memNode));
void *prgBrk = sbrk(0);
if (header->block + header->size == (size_t)prgBrk) {
if (head == tail) {
head = NULL;
tail = NULL;
} else {
memNode *tmp = head;
while (tmp != NULL) {
if (tmp->next == tail) {
tmp->next = NULL;
tail = tmp;
}
tmp = tmp->next;
}
}
sbrk(0 - (unsigned int)header->size - sizeof(memNode));
return;
}
header->isFree = 1;
}
+26
View File
@@ -0,0 +1,26 @@
#ifndef EX1_H
#define EX1_H
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define ALIGN(size, align) ((((size_t)size) + (align - 1)) & ~((size_t)align - 1))
#define IS_POWER_OF_2(num) ((num != 0) && ((num & (num - 1)) == 0))
struct newStruct
{
unsigned int size;
unsigned int is_free;
struct newStruct *next;
};
typedef struct newStruct blk;
static blk *head = NULL, *tail = NULL;
blk *find_fit(unsigned int size);
void *aligned_malloc(unsigned int size, unsigned int align);
void *aligned_free(void *ptr);
#endif // EX1_H
BIN
View File
Binary file not shown.
+86
View File
@@ -0,0 +1,86 @@
#include "ex1.h"
/* Tim block trong */
memNode *findFree(size_t size)
{
memNode *cur = head;
while (cur != NULL)
{
if (cur->isFree == 1 && cur->size >= size)
return cur;
cur = cur->next;
}
return NULL;
}
void *aligned_malloc(unsigned int size, unsigned int align)
{
if (size == 0)
return NULL;
/* Kiem tra so mu cua 2 */
if (ceil(log2((float)align)) != floor(log2((float)align)))
return NULL;
/* Tong gia tri do lon cua block can xin */
unsigned int total_size = size + align - 1 + sizeof(memNode);
memNode *header = findFree(total_size);
void *ret = NULL;
if (header != NULL)
{
header->isFree = 0;
ret = (void *)(((size_t)header + sizeof(memNode) + align - 1) & ~((size_t)align - 1));
*((void **)((size_t)ret - sizeof(memNode))) = header;
return ret;
}
void *block = sbrk(total_size);
if (block == (void *)-1)
return NULL;
header = block;
header->size = total_size;
header->block = (size_t)block;
header->isFree = 0;
header->next = NULL;
if (head == NULL)
head = header;
if (tail != NULL)
tail->next = header;
tail = header;
/* Tim vi tri tra ve thoa man */
ret = (void *)(((size_t)header + sizeof(memNode) + align - 1) & ~((size_t)align - 1));
/* Luu tru thong tin block tai khong gian truoc gia tri tra ve */
*((void **)((size_t)ret - sizeof(memNode))) = header;
return ret;
}
void aligned_free(void *ptr)
{
if (ptr == NULL)
return;
/* Lay lai thong tin cua block */
memNode *header = (memNode *)((size_t)ptr - sizeof(memNode));
void *prgBrk = sbrk(0);
/* Neu block nam o sat diem break */
if (header->block + header->size == (size_t)prgBrk)
{
if (head == tail)
{
head = NULL;
tail = NULL;
}
else
{
memNode *tmp = head;
while (tmp != NULL)
{
if (tmp->next == tail)
{
tmp->next = NULL;
tail = tmp;
}
tmp = tmp->next;
}
}
sbrk(0 - (unsigned int)header->size - sizeof(memNode));
return;
}
header->isFree = 1;
}
+15
View File
@@ -0,0 +1,15 @@
#include "ex1.h"
#include <math.h>
int main(int argc, char *argv[])
{
printf("PID: %d\n", getpid());
for (unsigned int align = 2; align <= pow(2, 22); align *= 2)
{
void *p = aligned_malloc(1024, align);
printf("%10d %p %15ld %ld \n", align, p,
(unsigned long)p, ((unsigned long)p) % align);
aligned_free(p);
}
return 0;
}
BIN
View File
Binary file not shown.
Binary file not shown.
+18
View File
@@ -0,0 +1,18 @@
#include <stdio.h>
#include <pthread.h>
void *hello(void *tid)
{
printf("Hello from thread %ld\n", (long)tid);
}
int main()
{
pthread_t tid[10];
long i;
for (i = 0; i < 10; i++)
{
pthread_create(&tid[i], NULL, hello, (void *)i);
pthread_join(tid[i], NULL);
}
pthread_exit(NULL);
}
BIN
View File
Binary file not shown.
+21
View File
@@ -0,0 +1,21 @@
all: pi_serial.o pi_multi-thread.o code.o
gcc -o pi_serial pi_serial.o
gcc -o pi_multi-thread pi_multi-thread.o -lpthread
gcc -o code code.o -lpthread
pi: pi_serial.o pi_multi-thread.o
gcc -o pi_serial pi_serial.o
gcc -o pi_multi-thread pi_multi-thread.o -lpthread
pi_serial: pi_serial.o
gcc -o pi_serial pi_serial.o
pi_multi-thread: pi_multi-thread.o
gcc -o pi_multi-thread pi_multi-thread.o -lpthread
code: code.o
gcc -o code code.o -lpthread
pi_serial.o: pi_serial.c
gcc -c pi_serial.c
pi_multi-thread.o: pi_multi-thread.c
gcc -c pi_multi-thread.c
code.o: code.c
gcc -c code.c
clean:
rm -rf *.o pi_serial pi_multi-thread code
Binary file not shown.
BIN
View File
Binary file not shown.
+38
View File
@@ -0,0 +1,38 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char *argv[])
{
clock_t t1, t2;
srand(time(NULL));
double x, y;
int count, nPoints, i;
if (argc != 2)
{
fprintf(stderr, "usage: pi_serial <integer value>\n");
return -1;
}
nPoints = atoi(argv[1]);
if (nPoints < 0)
{
fprintf(stderr, "%d must be >= 0\n", nPoints);
return -1;
}
time(&t1);
count = 0;
unsigned int state = rand();
for (i = 0; i < nPoints; ++i)
{
x = (double)rand_r(&state) / RAND_MAX;
y = (double)rand_r(&state) / RAND_MAX;
if (x * x + y * y - 1 <= 0)
{
++count;
}
}
time(&t2);
printf("Time to Execute: %lds\n", (t2 - t1));
printf("PI = %lf\n", 4 * (double)count / nPoints);
return 0;
}
Binary file not shown.
+71
View File
@@ -0,0 +1,71 @@
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM_THREADS 4
int n;
pthread_t thdArr[NUM_THREADS];
pthread_attr_t attr;
void *runner(void *arg)
{
long t = (long)arg;
double x, y;
long i, count;
count = 0;
for (i = 0; i < n; ++i)
{
x = ((double)rand() / RAND_MAX);
y = ((double)rand() / RAND_MAX);
if (x * x + y * y - 1 <= 0)
{
++count;
}
}
pthread_exit((void *)count);
}
int main(int argc, char *argv[])
{
clock_t t1, t2;
srand(time(NULL));
int count, rc, nPoints;
long t;
if (argc != 2)
{
fprintf(stderr, "usage: pi_multi-thread <integer value>\n");
return -1;
}
nPoints = atoi(argv[1]);
if (nPoints <= 0)
{
fprintf(stderr, "%d must be > 0\n", nPoints);
return -1;
}
n = nPoints / NUM_THREADS;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
t1 = clock();
for (t = 0; t < NUM_THREADS; ++t)
{
rc = pthread_create(&thdArr[t], &attr, runner, (void *)t);
if (rc)
{
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
count = 0;
for (t = NUM_THREADS; t >= 0; --t)
{
void *ret;
pthread_join(thdArr[t], &ret);
count += (long)ret;
}
t2 = clock();
printf("Time to Execute: %lf\n", (double)(t2 - t1) / CLOCKS_PER_SEC);
printf("PI = %lf\n", 4 * (double)count / nPoints);
return 0;
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
+67
View File
@@ -0,0 +1,67 @@
#include <stdlib.h>
#include "queue.h"
#include <pthread.h>
/* Remember to initilize the queue before using it */
void initialize_queue(struct pqueue_t *q)
{
q->head = q->tail = NULL;
pthread_mutex_init(&q->lock, NULL);
}
/* Return non-zero if the queue is empty */
int empty(struct pqueue_t *q)
{
return (q->head == NULL);
}
/* Get PCB of a process from the queue (q).
* Return NULL if the queue is empty */
struct pcb_t *de_queue(struct pqueue_t *q)
{
struct pcb_t *proc = NULL;
// TODO: return q->head->data and remember to update the queue's head
// and tail if necessary. Remember to use 'lock' to avoid race
// condition
// YOUR CODE HERE
if (empty(q))
return NULL;
pthread_mutex_lock(&q->lock);
proc = q->head->data;
struct qitem_t *pdel = q->head;
if (q->head == q->tail)
q->head = q->tail = NULL;
else
q->head = q->head->next;
free(pdel);
pthread_mutex_unlock(&q->lock);
return proc;
}
/* Put PCB of a process to the queue. */
void en_queue(struct pqueue_t *q, struct pcb_t *proc)
{
// TODO: Update q->tail.
// Remember to use 'lock' to avoid race condition
// YOUR CODE HERE
pthread_mutex_lock(&q->lock);
struct qitem_t *new_data = malloc(sizeof(struct qitem_t));
if (new_data == NULL)
return;
new_data->data = proc;
new_data->next = NULL;
if (empty(q))
{
q->head = q->tail = new_data;
}
else
{
q->tail->next = new_data;
q->tail = q->tail->next;
}
pthread_mutex_unlock(&q->lock);
}
BIN
View File
Binary file not shown.
+130
View File
@@ -0,0 +1,130 @@
#include "queue.h"
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#define TIME_UNIT 100 // In microsecond
static struct pqueue_t in_queue; // Queue for incomming processes
static struct pqueue_t ready_queue; // Queue for ready processes
static int load_done = 0;
static int timeslot; // The maximum amount of time a process is allowed
// to be run on CPU before being swapped out
// Emulate the CPU
void *cpu(void *arg)
{
int timestamp = 0;
/* Keep running until we have loaded all process from the input file
* and there is no process in ready queue */
while (!load_done || !empty(&ready_queue))
{
/* Pickup the first process from the queue */
struct pcb_t *proc = de_queue(&ready_queue);
if (proc == NULL)
{
/* If there is no process in the queue then we
* wait until the next time slice */
timestamp++;
usleep(TIME_UNIT);
}
else
{
/* Execute the process */
int start = timestamp; // Save timestamp
int id = proc->pid; // and PID for tracking
/* Decide the amount of time that CPU will spend
* on the process and write it to 'exec_time'.
* It should not exeed 'timeslot'.
*/
int exec_time = 0;
// TODO: Calculate exec_time from process's PCB
// YOUR CODE HERE
exec_time = (proc->burst_time > 2) ? 2 : proc->burst_time;
/* Emulate the execution of the process by using
* 'usleep()' function */
usleep(exec_time * TIME_UNIT);
/* Update the timestamp */
timestamp += exec_time;
// TODO: Check if the process has terminated (i.e. its
// burst time is zero. If so, free its PCB. Otherwise,
// put its PCB back to the queue.
// YOUR CODE HERE
proc->burst_time -= (timestamp - start);
if (proc->burst_time > 0)
en_queue(&ready_queue, proc);
/* Track runtime status */
printf("%2d-%2d: Execute %d\n", start, timestamp, id);
}
}
}
// Emulate the loader
void *loader(void *arg)
{
int timestamp = 0;
/* Keep loading new process until the in_queue is empty*/
while (!empty(&in_queue))
{
struct pcb_t *proc = de_queue(&in_queue);
/* Loader sleeps until the next process available */
int wastetime = proc->arrival_time - timestamp;
usleep(wastetime * TIME_UNIT);
/* Update timestamp and put the new process to ready queue */
timestamp += wastetime;
en_queue(&ready_queue, proc);
}
/* We have no process to load */
load_done = 1;
}
/* Read the list of process to be executed from stdin */
void load_task()
{
int num_proc = 0;
scanf("%d %d\n", &timeslot, &num_proc);
int i;
for (i = 0; i < num_proc; i++)
{
struct pcb_t *proc =
(struct pcb_t *)malloc(sizeof(struct pcb_t));
scanf("%d %d\n", &proc->arrival_time, &proc->burst_time);
proc->pid = i;
en_queue(&in_queue, proc);
}
}
int main()
{
pthread_t cpu_id; // CPU ID
pthread_t loader_id; // LOADER ID
/* Initialize queues */
initialize_queue(&in_queue);
initialize_queue(&ready_queue);
/* Read a list of jobs to be run */
load_task();
/* Start cpu */
pthread_create(&cpu_id, NULL, cpu, NULL);
/* Start loader */
pthread_create(&loader_id, NULL, loader, NULL);
/* Wait for cpu and loader */
pthread_join(cpu_id, NULL);
pthread_join(loader_id, NULL);
pthread_exit(NULL);
}
+6
View File
@@ -0,0 +1,6 @@
#!/bin/bash
echo "Input file:"
cat input.txt
echo "Results"
gcc sched.c queue.c -o sched -lpthread
cat input.txt | ./sched
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+11
View File
@@ -0,0 +1,11 @@
#ifndef QUEUE_H
#define QUEUE_H
#include "structs.h"
void initialize_queue(struct pqueue_t *q);
struct pcb_t *de_queue(struct pqueue_t *q);
void en_queue(struct pqueue_t *q, struct pcb_t *proc);
int empty(struct pqueue_t *q);
#endif
+36
View File
@@ -0,0 +1,36 @@
#include "queue.h"
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#define TIME_UNIT 100
static struct pqueue_t in_queue;
static struct pqueue_t ready_queue;
static int load_done = 0;
static int timeslot;
void *cpu(void *arg);
void *loader(void *arg);
void load_task();
int main()
{
pthread_t cpu_id;
pthread_t loader_id;
initialize_queue(&in_queue);
initialize_queue(&ready_queue);
load_task();
pthread_create(&cpu_id, NULL, cpu, NULL);
pthread_create(&loader_id, NULL, loader, NULL);
pthread_join(cpu_id, NULL);
pthread_join(loader_id, NULL);
pthread_exit(NULL);
}
BIN
View File
Binary file not shown.