semaphore

sesame·2022년 2월 11일
0

교육

목록 보기
29/46

https://1d1cblog.tistory.com/375

filedir.c

#include "th.h"

char *stat_name(char rcvmsg[BUFFER_SIZE]){
        struct stat statbuf;
        char *sndmsg = malloc(BUFFER_SIZE);

        if(stat(rcvmsg, &statbuf) < 0) out("stat error", NULL, 0, NULL);

        if(S_ISREG(statbuf.st_mode)){
                strcpy(sndmsg, "file");
        }
        else if(S_ISDIR(statbuf.st_mode)){
                strcpy(sndmsg, "directory");
        }
        return sndmsg;
}

void print_file(const char *path){
        int fd, n;
        unsigned char buf[BUFFER_SIZE];

        fd = open(path, O_RDONLY);
        if(fd < 0) out("open error", NULL, fd, NULL);
        for(;;){
                n = read(fd, buf, sizeof buf);

                if(n < 0) out("read error", NULL, fd, NULL);

                if(n == 0) break;

                if(write(STDOUT_FILENO, buf, n) < 0) out("write error", NULL, fd, NULL);
        }
        if(close(fd) < 0) out("close error", NULL, fd, NULL);
}

void print_file_lib(const char *path){
        char *n;
        unsigned char buf[BUFFER_SIZE];

        FILE *f = fopen(path, "r");
        if(!f) out("fopen error", f, 0, NULL);

        while(1){
                n = fgets(buf, BUFFER_SIZE, f);
                if(!n) break;
                printf("%s", buf);
        }
        if(fclose(f) == EOF) out("fclose error", f, 0, NULL);
}
void print_dir(char *path) {
        DIR *d;
        struct dirent *ent;
        struct stat st;

        d = opendir(path);
        if(!d) out("opendir error", NULL, 0, d);

        while(ent = readdir(d)){
                char fpath[BUFFER_SIZE] = { };
                strcat(fpath, path);
                strcat(fpath, "/");
                strcat(fpath, ent->d_name);
                
                if(stat(fpath, &st) < 0) out("dir: stat error", NULL, 0, NULL);

                if(S_ISDIR(st.st_mode)){
                        printf("%s/\n", ent->d_name);
                }else if(S_ISREG(st.st_mode)) printf("%s*\n", ent->d_name);
        }
        closedir(d);
}
void out(const char *s, FILE *f, int fd, DIR *d){
        perror(s);
        if(f) fclose(f);
        if(fd) close(fd);
        if(d) closedir(d);
        exit(1);
}

inout.c

#include "th.h"

char *input_msg(){
        char *str = malloc(BUFFER_SIZE);

        printf("\nfile or directory name: ");
        scanf("%s", str); getchar();

        return str;
}

void output_msg(char rcvmsg[BUFFER_SIZE], char sndmsg[BUFFER_SIZE]){
        if(!strcmp(rcvmsg, "file"))
                print_file_lib(sndmsg);
        else if(!strcmp(rcvmsg, "directory"))
                print_dir(sndmsg);
}

sem.c

#include "th.h"

void s_init(sem_t sem, unsigned int val){
        if(sem_init(&sem, 0, val) == -1){
                perror("sem_init error");
                exit(1);
        }
}

void s_destroy(sem_t sem){
        sem_destroy(&sem);
}

void s_wait(sem_t sem){
        sem_wait(&sem);
}

void s_post(sem_t sem){
        sem_post(&sem);
}

shm.c

#include "th.h"

void create_shm(key_t key, size_t size){
        shmid = shmget(key, size, 0666|IPC_CREAT|IPC_EXCL);
        if (shmid == -1){
                perror("shmget failed : ");
                exit(0);
        }
}

char *at_shm(int shmid){
        char *shared_memory;
        shared_memory = shmat(shmid, (void *)0, 0);
        if (shared_memory == (void *)-1){
                perror("shmat failed : ");
                exit(0);
        }
        return shared_memory;
}

void rmv_shm(){
        if(shmctl(shmid,IPC_RMID,NULL)==-1){
                printf("shmctl failed\n");
        }
}

th.h

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <semaphore.h>
#define BUFFER_SIZE 2048

union semun{
        int val;
        struct semid_ds *buf;
        unsigned short *array;
};

int shmid;
static sem_t sem_one, sem_two, sem_three;

char *stat_name(char rcvmsg[BUFFER_SIZE]);
void print_file(const char *path);
void print_file_lib(const char *path);
void print_dir(char *path);
void out(const char *s, FILE *f, int fd, DIR *d);

void s_wait(sem_t sem);
void s_post(sem_t sem);
void s_init(sem_t sem, unsigned int val);
void s_destroy(sem_t sem);

void create_shm(key_t key, size_t size);
char *at_shm(int shmid);
void rmv_shm();

pthread_t create_thread(pthread_t thread, void *(*start_routine)(void *));
void join_thread(pthread_t thread);
void *sub_thread(void *command);

char *input_msg();
void output_msg(char rcvmsg[BUFFER_SIZE], char sndmsg[BUFFER_SIZE]);

thread.c

#include "th.h"

pthread_t create_thread(pthread_t thread, void *(*start_routine)(void *)){
        if(pthread_create(&(thread), NULL, start_routine, NULL))
                out("pthread create error", NULL, 0, NULL);
        return thread;
}

void join_thread(pthread_t thread){
        printf("join thread\n");
        if(pthread_join(thread, NULL))
                out("pthread_join error", NULL, 0, NULL);
}

void *sub_thread(void *command){
        struct stat statbuf;
        char *shared_memory;
        char sndmsg[BUFFER_SIZE];
        char rcvmsg[BUFFER_SIZE];

        pthread_t tid;

        tid = pthread_self();
        printf("[tid]: %lx\n", tid);

        while(1){
                printf("sub1\n");
                printf("one: 1 -> 0\n");
                sem_wait(&sem_one);  //1 -> 0
                printf("22222\n");

                printf("sub2\n");
                printf("shmid: %d\n", shmid);
                shared_memory = at_shm(shmid);

                printf("1sub, name: %s\n\n", shared_memory);

                if(!strcmp(shared_memory, "exit")){
                        break;
                }

                sprintf(shared_memory, "%s", stat_name(shared_memory));
                printf("2sub, name: %s\n\n", shared_memory);
                printf("sub3\n");

                printf("two: 0 -> 1\n");
                sem_post(&sem_two); //0 -> 1

                printf("sub4\n");
        }
}

main.c

#include "th.h"

int main(int argc, char *argv[]){
        key_t key = 12345;
        pthread_t thread;
        char *shared_memory;
        char sndmsg[BUFFER_SIZE];
        char rcvmsg[BUFFER_SIZE];

        create_shm(key, BUFFER_SIZE);
        sem_init(&sem_one, 0, 0);
        sem_init(&sem_two, 0, 1);


        thread = create_thread(thread, sub_thread);
        sleep(1);

        while(1){
                printf("two: 1 -> 0\n");
                sem_wait(&sem_two);  //1 -> 0


                strcpy(sndmsg, input_msg());
                printf("main3\n");

                if(!strlen(sndmsg)){
                        printf("no command\n");
                        continue;
                }

                printf("main4\n");
                shared_memory = at_shm(shmid);
                sprintf(shared_memory, "%s", sndmsg);

                sleep(2);

                printf("main5\n");

                printf("main, name: %s\n", shared_memory);

                if(!strcmp(sndmsg, "exit")){
                        sleep(1);
                        break;
                }

                printf("main2, stat: %s\n", shared_memory);

                output_msg(shared_memory, sndmsg);
                printf("main output: %s, %s\n", shared_memory, sndmsg);

                printf("one: 0 -> 1\n");
                sem_post(&sem_one);  //0 -> 1
                printf("111111\n");

                sleep(1);

        }

        rmv_shm();

        join_thread(thread);

        exit(0);
}

makefile

a.out: main.o shm.o thread.o filedir.o inout.o sem.o
        gcc -g -pthread -o a.out main.o shm.o thread.o filedir.o inout.o sem.o

main.o: th.h main.c
        gcc -c -o main.o main.c

shm.o: th.h shm.c
        gcc -c -o shm.o shm.c

sem.o: th.h sem.c
        gcc -c -o sem.o sem.c

thread.o: th.h thread.c
        gcc -c -o thread.o thread.c

filedir.o: th.h filedir.c
        gcc -c -o filedir.o filedir.c

inout.o: th.h inout.c
        gcc -c -o inout.o inout.c

lock.c

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

void * read(void * arg);
void * accu(void * arg);
static sem_t sem_one;
static sem_t sem_two;
static int num;

int main(int argc, char *argv[]){
        pthread_t id_t1, id_t2;
        sem_init(&sem_one, 0, 0);
        sem_init(&sem_two, 0, 1);

        //pthread_create(&id_t1, NULL, read, NULL);
        pthread_create(&id_t2, NULL, accu, NULL);

        for(int i=0; i<5; i++){
                fputs("Input num: ", stdout);

                printf("two: 1 -> 0\n");
                sem_wait(&sem_two);             // sem_two 열쇠 감소(count : 1 -> 0)
                scanf("%d", &num);
                printf("one: 0 -> 1\n");
                sem_post(&sem_one);             // sem_one 열쇠를 하나 줌(count : 0 -> 1)
                printf("\n");
        }

        pthread_join(id_t1, NULL);
        pthread_join(id_t2, NULL);

        sem_destroy(&sem_one);
        sem_destroy(&sem_two);
        return 0;
}

void * read(void * arg){
        int i;
        for(i=0; i<5; i++){
                fputs("Input num: ", stdout);

                printf("two: 1 -> 0\n");
                sem_wait(&sem_two);             // sem_two 열쇠 감소(count : 1 -> 0)
                scanf("%d", &num);
                printf("one: 0 -> 1\n");
                sem_post(&sem_one);             // sem_one 열쇠를 하나 줌(count : 0 -> 1)
        }
}
void * accu(void * arg){
        int sum=0, i;
        for(i=0; i<5; i++){
                printf("one: 1 -> 0\n");
                sem_wait(&sem_one);             // sem_one 열쇠 감소(count : 1 -> 0)
                sum+=num;
                printf("%d\n", sum);
                printf("two: 0 -> 1\n");
                sem_post(&sem_two);             // sem_two 열쇠를 하나 줌(count : 0 -> 1)
        }
}

0개의 댓글