[태그:] c

  • mutex 예제

    linux system programming, 238p. 두 시간 삽질했다. thread arg 를 포인터로 주는데 여러 개를 쓰려면 struct로 정의해서 써야 한댄다. 맞는지 틀린지..

    #include <pthread.h>
    #include <stdio.h>
    #include <unistd.h>
    
    
    //arg를 여러 파라미터로 사용하기 위해,
    //구조체로 정의
    //https://stackoverflow.com/questions/52812004/parameter-passing-multiple-values-using-void-pointer
    //여기 참조
    //공유 자원.
    int sharedInt=0;
    //mutex 설정.
    static pthread_mutex_t the_mutex = PTHREAD_MUTEX_INITIALIZER;
    
    struct myStruct {
    	//struct는 initilizer를 지원하지 않음.
    	char *message;
    	int index;
    	//index를 보고 입력된 파라미터로 hello, one, two, three를 선택.
    	//이렇게 구현하려 했으나, 힘들어 문자열로 변경.
    	//index로 sharedInt를 업데이트 하려 했으나,
    	//잘 안됨..
    	//스레드가 시작할 때마다 sharedInt를 업데이트 하면 기존 값을
    	//버리고 다시 씀!!
    	//thread 안에서만 공유 자원을 조작..
    
    
    };
    
    
    
    void* start_routine(void* arg ){
    	int pid;
    	int threadID;
    	//struct로 arg를 받기 위해, 
    	//struct로 변경.
    	struct myStruct *temp;
    
    	temp = arg;
    	//pointer 로 global 변수 변경
    
    	//pthread_mutex_lock(&the_mutex);
    	//sharedInt = temp->index;
    
    	//printf("my thread sentence is \"%s\"\n", temp->message);
    	//printf("temp->index is %d\n", temp->index);
    
    	pthread_mutex_lock(&the_mutex);
    
    	printf("SharedInt는 %d\n",sharedInt);
    	if(sharedInt == 0){
    		//strsep(temp->message, " ");
    		//printf("my thread word is %s\n",outputword);
    		printf("zero\n");
    		//temp->index++;
    
    	}
    
    	else if(sharedInt == 1){
    		//printf("my thread word is %s\n",outputword);
    		printf("one\n");
    		//temp->index++;
    
    	}
    	else if(sharedInt == 2){
    		printf("two\n");
    		//temp->index++;
    
    	}
    
    	else{
    		printf("three or more\n");
    	}
    	sharedInt++;
    
    	pthread_mutex_unlock(&the_mutex);
    
    	}
    
    int main(){
    
    	pthread_t thread[2];
    	int ret, errorno;
    	struct myStruct message = {"hello one two three", 0 };
    	printf("myStruct message index는 %d\n", message.index);
    	//아래 부분은 불필요 부분. thread 밖에서 조작하여 무의미함.
    	//message.index=2;
    
    	ret = pthread_create(&thread[0],NULL,start_routine,(void*)&message);
    
    	if(ret<0){
    		errorno = ret;
    		//printf("%d\n",errorno);
    		perror("pthread_create");
    		return -1;
    	}
    	//아래 부분은 불필요 부분. thread 밖에서 조작하여 무의미함.
    	//message.index=1;
    
    	//printf("myStruct message index는 %d\n", message.index);
    
    	//printf("struct 출력: %d",message.index);
    	//printf("message 확인 %d",message.index);
    
    	ret = pthread_create(&thread[1],NULL,start_routine,(void*)&message);
    
    	if(ret<0){
    		errorno = ret;
    		//printf("%d\n",errorno);
    		perror("pthread_create");
    		return -1;
    	}
    
    	//각 스레드 끝나길 대기
    
    	pthread_join(thread[0],NULL);
    	pthread_join(thread[1],NULL);
    	//mutex 삭제
    	pthread_mutex_destroy(&the_mutex);
    	printf("completed\n");
    	return 0;
    
    }
    

    100번 돌리면 mutex lock을 설정한 경우와 설정하지 않은 경우 값이 다름. 나름 이해했다고 믿고 싶다.

  • thread 예제

    linux system programming, 234p

    https://bitsoul.tistory.com/m/157 여기 참조.

    #include <pthread.h>
    #include <stdio.h>
    #include <unistd.h>
    
    
    void* start_routine(void* arg ){
    	int pid;
    	int threadID;
    	pid= getpid();
    	printf("pid is %d\n", pid);
    	threadID = pthread_self();
    	printf("tid is %lu\n",threadID);
    	printf("data is %s\n",arg);
    	}
    
    int main(){
    	pthread_t thread[2];
    	const char *message1="hello one";
    	const char *message2="hello two";
    	const char *message3="hello main";
    
    	int ret, errorno;
    	ret = pthread_create(&thread[0],NULL,start_routine,(void*)message1);
    	if(ret<0){
    		errorno = ret;
    		//printf("%d\n",errorno);
    		perror("pthread_create");
    		return -1;
    	}
    	ret = pthread_create(&thread[1],NULL,start_routine,(void*)message2);
    	if(ret<0){
    		errorno = ret;
    		//printf("%d\n",errorno);
    		perror("pthread_create");
    		return -1;
    	}
    
    
    
    	/*
    	for(int i=0;i<2;i++){
    		ret = pthread_create(&thread[i],NULL,start_routine,NULL);
    		if(!ret){
    			errorno = ret;
    			printf("%d\n",errorno);
    			perror("pthread_create");
    			return -1;
    		}
    	}
    	*/
    	int thread_compare=0;
    	//스레드가 다르면 0, 같으면 0이 아는 수 리턴.
    	//다른 스레드로 0을 리턴.
    	thread_compare = pthread_equal(thread[0], thread[1]);
    	printf("thread is same? %d\n",thread_compare);
    	sleep(1);
    	//메인에서  start_routine.
    	start_routine((void*)message3);
    
    
    	//각 스레드 끝나길 대기
    
    	pthread_join(thread[0],NULL);
    	pthread_join(thread[1],NULL);
    	return 0;
    
    }
    

    위 코드를 실행하면 아래와 같다. race condition으로 매 실행 다른 결과를 보았다.

    pi@raspberrypi:~/Project/cCode/systemProgram $ gcc -lpthread mythread.c ;./a.out 
    thread is same? -1235590048
    pid is 14996
    tid is 3059377248
    data is hello two
    pid is 14996
    tid is 3067769952
    data is hello one
    pid is 14996
    tid is 3069673600
    data is hello main
    pi@raspberrypi:~/Project/cCode/systemProgram $ gcc -lpthread mythread.c ;./a.out 
    pid is 15068
    tid is 3067769952
    data is hello one
    pid is 15068
    tid is 3059377248
    data is hello two
    thread is same? 0
    pid is 15068
    tid is 3069673600
    data is hello main
    pi@raspberrypi:~/Project/cCode/systemProgram $ gcc -lpthread mythread.c ;./a.out 
    pid is 15125
    tid is 3068077152
    data is hello one
    thread is same? 0
    pid is 15125
    tid is 3059684448
    data is hello two
    pid is 15125
    tid is 3069980800
    data is hello main
    

    gnu c는 pthread가 전부인가 보다.

  • daemon 예제

    linux system programming, 174p 예제 실행.

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <linux/fs.h>
    
    int main (void)
    
    {
    	pid_t pid, sid;
    	int i;
    	int j=0;
    	/* create new process */
    	pid = fork ();
    	printf("Pid is %d \n",pid);
    	if (pid == -1)
    		return -1;
    	else if (pid != 0)
    		exit (EXIT_SUCCESS);
    
    
    	/* create new session */
    	sid =setsid();
    	if (sid == -1)
    		return -1;
    
    	printf("sid is %d \n",sid);
    	/* set the working directory to the root directory */
    	if (chdir("/") == -1){
    		printf("check");
    		return -1;
    	}
    
    	/* close all open files--NR_OPEN is overkill, but works */
    	printf("FOPEN_MAX is %d\n",FOPEN_MAX);
    	for (i = 0; i < FOPEN_MAX; i++){
    		//j=close(i);
    		close(i);
    		//printf("%d\n", j);
    		printf("%d is closed\n", i);
    	}
    
    	/* redirect fd's 0,1,2 to /dev/null */
    	open("/dev/null", O_RDWR); /* stdin */
    	dup(0); /* stdout */
    	dup(0); /* stderror */
    	/* do its daemon thing... */
    
    	while(1){
    
    		sleep(1);
    		//printf("this is test\n");
    	}
    
    	return 0;
    
    }
    

    54번 행 printf가 나오지 않음은 stdout을 죽여서 그런 듯 하다.

    NR_OPEN을 찾을 수 없는데, 옛날 프로그램이라 다른 문구로 정의된 듯 하다. FOPEN_MAX로 일단 했다.

    pi@raspberrypi:~/Project/cCode/systemProgram $ gcc daemon.c ;./a.out;ps aux | grep pi;
    Pid is 1939 
    Pid is 0 
    sid is 1939 
    FOPEN_MAX is 16
    0 is closed
    message+   346  0.0  0.0   6736  3524 ?        Ss    6월22   0:04 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
    avahi      350  0.0  0.0   5896  2960 ?        Ss    6월22   0:02 avahi-daemon: running [raspberrypi.local]
    pi         846  0.0  0.1  14716  7204 ?        Ss    6월22   0:12 /lib/systemd/systemd --user
    pi         849  0.0  0.0  16864  1772 ?        S     6월22   0:00 (sd-pam)
    pi         891  0.0  0.0   7256  3568 tty1     S+    6월22   0:00 -bash
    pi        1939  0.0  0.0   1852    64 ?        Ss   19:01   0:00 ./a.out
    pi        1940  0.0  0.0   8552  2532 pts/1    R+   19:01   0:00 ps aux
    pi        1941  0.0  0.0   6116   496 pts/1    S+   19:01   0:00 grep --color=auto pi
    root     28022  0.0  0.1  12236  6304 ?        Ss   17:16   0:00 sshd: pi [priv]
    pi       28033  0.0  0.0  12236  3532 ?        S    17:16   0:01 sshd: pi@pts/0
    pi       28036  0.0  0.0   7392  3856 pts/0    Ss   17:16   0:00 -bash
    pi       28244  0.1  0.1  11564  6728 pts/0    S+   17:19   0:06 vi daemon.c
    root     28246  0.0  0.1  12236  6252 ?        Ss   17:19   0:00 sshd: pi [priv]
    pi       28257  0.0  0.0  12236  3552 ?        S    17:19   0:00 sshd: pi@pts/1
    pi       28260  0.0  0.0   7548  3924 pts/1    Ss   17:19   0:00 -bash
    

    pid 1939가 ?로 대몬으로 변신했다.