Linux 系統與程式設計

tags: Linux 系統與程式設計

20170303

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

int main(void) {
/* Press any Integer */
	int n;
	scanf("%d", &n);

/* Use "fork()" to create Child's and Parent's process */
	int ret = fork();
	int result = n;	// Set the "result" initial value

	if (ret == 0) {	// Child's entry
		printf("\n***** Child's pid = %d *****\n", getpid());
		while (n --> 0)
			result += n;
		printf("1 + 2 + ... + n = %d\n", result);
		exit(0);
	
	} else {	// Parent's entry
		printf("***** Parent's pid = %d *****\n", getpid());
		printf("n 的因數:%d", n);
		while (n --> 1)
			if (result % n == 0)
				printf("\t%d", n);
		exit(0);
	}
}

延伸學習

20170310

(一) Unix system call

1. execv()

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

char * argv[] = {"/bin/ls", "-1", 0};
int main(void) {

	int pid, status;

	if ((pid = fork()) < 0) {
		printf("Fork error \n");
		exit(1);
	}
	
	if (pid == 0) {	/* Child executes here */
		execv (argv[0], argv);
		printf("Exec error \n");
		exit(1);
	} else		/* Parent executes here */
		wait(&status);

	printf("Hello there! \n");
	return 0;
}

(二) Signals

1. UNIX Process Control

2. kill Command

kill -signal pid

3. Function Call

int ret = raise(SIGINT); /* Process commits suicide. */
assert(ret != 0);        /* Shouldn't get here. */

int kill(pid_t iPid, int iSig);

pid_t iPid = getpid(); /* Process gets its id.*/
kill(iPid, SIGINT);
/* Process sends itself a SIGINT signal (commits suicide?) */

4. Linux Signal

5. 訊號處理 - signal.h

(1) signal()
#include <signal.h>
void(*signal(int sig, void (*func)(int)))(int) ;
#include <signal.h>
#include <stdio.h>
#include <unistd.h>

void ouch(int sig) {
	printf("OUCH! - I got signal %d\n", sig);
	(void) signal(SIGINT, SIG_DFL);
}

int main(void) {
	(void) signal(SIGINT, ouch);
	
	while(1) {
		printf("Hello World!\n");
		sleep(1);
	}
}
(2) sigaction()
#include <signal.h>
int sigaction(int sig,const struct sigaction *act, struct sigaction *oact);
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>


// When the process get the "Ctrl+C" signal.
void show_time() {
    system("date"); // show the time.
}

// When the process gets the "Ctrl+\" signal.
void go_default() {
    signal(SIGINT, SIG_DFL);    // recover "Ctrl+C"
}


int main(void) {

    signal(SIGINT, show_time);  // triggering "Ctrl+C"
    signal(SIGQUIT, go_default);// triggering "Ctrl+\"

    while(1) {
        printf("What time is it?\n");  // Something interesting will happen if this line without "\n".
        sleep(1);
    }   
}

20170317

1. What is a Thread?

(1) OS view

(2) Software developer view

[Example]

  1. Computer games
    • each thread controls the movement of an object.
  2. Scientific simulations
    • Hurricane movement simulation: each thread simulates the hurricane in a small domain.
    • Molecular dynamic: each thread simulates a subset of particulars.
  3. Web server
    • Each thread handles a connection.

2. Process and Thread

(1) Process context

(2) Threads

3. Pthreads

(1) The Pthreads API

(2) Thread management

  1. Creation
    • pthread_create
  2. Termination
    • Return
    • Pthread_exit
    • Can we still use exit?
  3. Wait (parent/child synchronization)
    • pthread_join
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h> 
#include <time.h>

#define NUM_THREADS 10
#define MSIZE 100

// 找出 1 - 100 的所有質數

static double getDoubleTime();
void *thread_function(void *arg);
pthread_mutex_t work_mutex;

// 宣告 prime_array 陣列
int prime_array[NUM_THREADS][(MSIZE / NUM_THREADS)];


int main(void) {
	int res;
	pthread_t a_thread[NUM_THREADS];
	void *thread_result;
	int lots_of_threads;
    int print_prime = 0;


	// start to measure time...
	double start_time = getDoubleTime();
	
	// initialize mutex...
	res = pthread_mutex_init(&work_mutex, NULL);
	if (res != 0) {
       	perror("Mutex initialization failed");
	    exit(EXIT_FAILURE);
    }

	// pthread_create...
	for (lots_of_threads = 0; lots_of_threads < NUM_THREADS; lots_of_threads ++) {
		res = pthread_create(&(a_thread[lots_of_threads]), NULL, thread_function, (void*)(long)lots_of_threads);

        if (res != 0) {
			perror("Thread creation failed");
        		exit(EXIT_FAILURE);
		}
	}

	// pthread_join...
	for (lots_of_threads = NUM_THREADS - 1; lots_of_threads >= 0; lots_of_threads--) {
        	res = pthread_join(a_thread[lots_of_threads], &thread_result); 

            if (res != 0) {
	            perror("pthread_join failed");
        	}
    }	
    
    /* 輸出 prime_array 陣列 */
    int i = 0;  // 設定計數器
    for (lots_of_threads = 0; lots_of_threads < NUM_THREADS; lots_of_threads ++) { 
        printf("\n\nThe thread[%d]'s numbers:\n", lots_of_threads);
        
        for (i = 0; i < (MSIZE / NUM_THREADS); i++) {
            if (prime_array[lots_of_threads][i] != 0)
                printf("%d\t", prime_array[lots_of_threads][i]);                        }
    }

	printf("\nThread joined\n");

	// stop measuring time...
	double finish_time = getDoubleTime();
	printf("Execute Time:  %.3lf ms\n", (finish_time - start_time));
    exit(EXIT_SUCCESS);
}


void *thread_function(void *arg) {
    // pthread_mutex_lock(&work_mutex);
	
    int my_num = (long)arg;
	// if (MSIZE % NUM_THREADS != 0){    printf("error");   pthread_exit(-1);    }

    int start_num = (MSIZE / NUM_THREADS) * my_num + 1;
	int end_num = (MSIZE / NUM_THREADS) * (my_num + 1);

    int i = 0, j = 0, k = 0;   // Set the loop
    int count = 0;      // Set the counter
    int result = 0;     // result

    printf("I'm thread[%d], start_num:%d, end_num:%d\n", my_num, start_num, end_num);

    /* find the prime number */
    for (i = start_num; i <= end_num; i++) {
        count = 0;      // Reset counter

        for (j = 1; j <= i; j++) {
            if (i % j == 0)
                count += 1;
        }
        
        if (count == 2) { 
            prime_array[my_num][k] = i;
            k++;
        }
    }


    // pthread_mutex_unlock(&work_mutex);
	pthread_exit(0);
}


static double getDoubleTime() {
        struct timeval tm_tv;
        gettimeofday(&tm_tv,0);
        return (double)(((double)tm_tv.tv_sec * (double)1000. + (double)(tm_tv.tv_usec)) * (double)0.001);
}

20170324

一、Pthreads

pthread.h

#include <pthread.h>

int pthread_create(pthread_t *thread, pthread_attr_t
*attr, void *(*start_routine)(void *), void *arg);
//create a thread


void pthread_exit(void *retval);
//terminate a thread


int pthread_join(pthread_t th, void **thread_return);
//wait for thread termination


int pthread_cancel(pthread_t thread);
//cancel a thread


int pthread_setcancelstate(int state, int *oldstate);
//set cancellation state


int pthread_setcanceltype(int type, int *oldtype);
//set cancellation type
pthread_create()
int pthread_create(pthread_t *thread,
pthread_attr_t *attr, void *(*start_routine)(void
*), void *arg);
pthread_exit()
void pthread_exit(void *retval);
pthread_join()
int pthread_join(pthread_t th, void **thread_return);
pthread_setcancelstate()
int pthread_setcancelstate(int state, int *oldstate);
pthread_setcanceltype()
int pthread_setcanceltype(int type, int *oldtype);

二、Condition Variables

pthread_cond_init (condition, attr)

pthread_cond_destroy (condition)

pthread_condattr_init (attr)

pthread_condattr_destroy (attr)

三、Thread Synchronization

1. Semaphore

semaphore.h

#include <semaphore.h>

int sem_init(sem_t *sem, int pshared, unsigned int value);
//create a semaphore


int sem_wait(sem_t *sem);
//lock a semaphore


int sem_post(sem_t *sem);
//unlock a semaphore


int sem_destroy(sem_t *sem);
//delete a semaphore
sem_init()
int sem_init(sem_t *sem, int pshared, unsigned
int value);
sem_wait()
int sem_wait(sem_t *sem);
sem_post()
int sem_post(sem_t *sem);
sem_destroy()
int sem_destroy(sem_t *sem);
//delete a semaphore

2. Mutex

pthread.h

#include <pthread.h>

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
//create a mutex


int pthread_mutex_lock(pthread_mutex_t *mutex);
//lock a mutex


int pthread_mutex_unlock(pthread_mutex_t *mutex);
//unlock a mutex


int pthread_mutex_destroy(pthread_mutex_t *mutex);
//delete a mutex
pthread_mutex_init()
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
pthread_mutex_lock()
int pthread_mutex_lock(pthread_mutex_t *mutex);
//lock a mutex
pthread_mutex_unlock()
int pthread_mutex_unlock(pthread_mutex_t *mutex);
//unlock a mutex
pthread_mutex_destroy()
int pthread_mutex_destroy(pthread_mutex_t *mutex);
//delete a mutex

課程作業

/* * Solution to Producer Consumer Problem * Using Ptheads, a mutex and condition variables * From Tanenbaum, Modern Operating Systems, 3rd Ed. */ /* In this version the buffer is a single number. The producer is putting numbers into the shared buffer (in this case sequentially) And the consumer is taking them out. If the buffer contains zero, that indicates that the buffer is empty. Any other value is valid. */ #include <stdio.h> #include <pthread.h> #define MAX 10 /* Numbers to produce */ #define buf_max 5 pthread_mutex_t the_mutex; pthread_cond_t condc, condp; int buffer[5]; int in = 0; int count = 0; void *producer(void *ptr) { int i = 0; for (i = 1; i <= MAX; i++) { pthread_mutex_lock(&the_mutex); /* protect buffer */ while (count == buf_max) /* If there is something in the buffer then wait */ pthread_cond_wait(&condp, &the_mutex); in++; buffer[in] = i; printf("ProBuffer[%d]:%2d\n", in, buffer[in]); count++; pthread_cond_signal(&condc); /* wake up consumer */ pthread_mutex_unlock(&the_mutex); /* release the buffer */ } pthread_exit(0); } void *consumer(void *ptr) { int i = 0; for (i = 1; i <= MAX; i++) { pthread_mutex_lock(&the_mutex); /* protect buffer */ while (count == 0) /* If there is nothing in the buffer then wait */ pthread_cond_wait(&condc, &the_mutex); printf("ConBuffer[%d]:%2d\n", in, buffer[in]); buffer[in] = 0; in--; count--; pthread_cond_signal(&condp); /* wake up consumer */ pthread_mutex_unlock(&the_mutex); /* release the buffer */ } pthread_exit(0); } int main(int argc, char **argv) { pthread_t pro, con; // Initialize the mutex and condition variables /* What's the NULL for ??? */ pthread_mutex_init(&the_mutex, NULL); pthread_cond_init(&condc, NULL); /* Initialize consumer condition variable */ pthread_cond_init(&condp, NULL); /* Initialize producer condition variable */ // Create the threads pthread_create(&con, NULL, consumer, NULL); pthread_create(&pro, NULL, producer, NULL); // Wait for the threads to finish // Otherwise main might run to the end // and kill the entire process when it exits. pthread_join(con, NULL); pthread_join(pro, NULL); // Cleanup -- would happen automatically at end of program pthread_mutex_destroy(&the_mutex); /* Free up the_mutex */ pthread_cond_destroy(&condc); /* Free up consumer condition variable */ pthread_cond_destroy(&condp); /* Free up producer condition variable */ }

20170331

Socket Programming

1. What is a socket?

2. Two essential types of sockets

(1) SOCK_STREAM

(2) SOCK_DGRAM

Example

/* Make the necessary includes and set up the variables. */ #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> int main() { int server_sockfd, client_sockfd; int server_len, client_len; struct sockaddr_in server_address; struct sockaddr_in client_address; /* Create an unnamed socket for the server. */ server_sockfd = socket(AF_INET, SOCK_STREAM, 0); /* Name the socket. */ server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = inet_addr("127.0.0.1"); server_address.sin_port = 9734; server_len = sizeof(server_address); bind(server_sockfd, (struct sockaddr *)&server_address, server_len); /* Create a connection queue and wait for clients. */ listen(server_sockfd, 5); while(1) { char ch; printf("server waiting\n"); /* Accept a connection. */ client_len = sizeof(client_address); client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, &client_len); /* We can now read/write to client on client_sockfd. */ read(client_sockfd, &ch, 1); printf("receive from client = %c\n", ch); ch++; write(client_sockfd, &ch, 1); close(client_sockfd); } }
/* Make the necessary includes and set up the variables. */ #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> int main() { int sockfd; int len; struct sockaddr_in address; int result; char ch = 'A'; /* Create a socket for the client. */ sockfd = socket(AF_INET, SOCK_STREAM, 0); /* Name the socket, as agreed with the server. */ address.sin_family = AF_INET; address.sin_addr.s_addr = inet_addr("127.0.0.1"); address.sin_port = 9734; len = sizeof(address); /* Now connect our socket to the server's socket. */ result = connect(sockfd, (struct sockaddr *)&address, len); if(result == -1) { perror("oops: client2"); exit(1); } /* We can now read/write via sockfd. */ write(sockfd, &ch, 1); read(sockfd, &ch, 1); printf("char from server = %c\n", ch); close(sockfd); exit(0); }

課程作業

/* Make the necessary includes and set up the variables. */ #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> int main() { int server_sockfd, client_sockfd; int server_len, client_len; struct sockaddr_in server_address; struct sockaddr_in client_address; /* Create an unnamed socket for the server. */ server_sockfd = socket(AF_INET, SOCK_STREAM, 0); /* Name the socket. */ server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = inet_addr("127.0.0.1"); server_address.sin_port = 9734; server_len = sizeof(server_address); bind(server_sockfd, (struct sockaddr *)&server_address, server_len); /* Create a connection queue and wait for clients. */ listen(server_sockfd, 5); while(1) { printf("\nserver waiting\n"); /* Accept a connection. */ client_len = sizeof(client_address); client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, &client_len); /* We can now read/write to client on client_sockfd. */ int i, j, tmp = 0, get_n; int *buf; read(client_sockfd, &get_n, sizeof(get_n)); buf = (int *) malloc(get_n * sizeof(int)); read(client_sockfd, buf, get_n * sizeof(int)); printf("sort arr[%d] from client:\n", get_n); for (i = 0; i < get_n; i++) { for (j = 0; j < get_n; j++) { if (buf[i] < buf[j]) { tmp = buf[i]; buf[i] = buf[j]; buf[j] = tmp; } } } for (i = 0; i < get_n; i++) printf("arr[%d] = %d\n", i, buf[i]); write(client_sockfd, buf, get_n * sizeof(buf)); close(client_sockfd); } }
/* Make the necessary includes and set up the variables. */ #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> #define SIZE 5 int main() { int sockfd; int len; struct sockaddr_in address; int result, n; /* Create a socket for the client. */ sockfd = socket(AF_INET, SOCK_STREAM, 0); /* Name the socket, as agreed with the server. */ address.sin_family = AF_INET; address.sin_addr.s_addr = inet_addr("127.0.0.1"); address.sin_port = 9734; len = sizeof(address); /* Now connect our socket to the server's socket. */ result = connect(sockfd, (struct sockaddr *)&address, len); if (result == -1) { perror("oops: client!"); exit(1); } /* We can now read/write via sockfd. */ int i, j, tmp = 0, s = SIZE; int arr[SIZE] = {4, 7, 1, 8, 3}; int rec[SIZE] = {0, 0, 0, 0, 0}; printf("%d\n", s); write(sockfd, &s, sizeof(int)); printf("\noriginal from client - arr[]\n"); for (i = 0; i < SIZE; i++) printf("arr[%d] = %d\n", i, arr[i]); write(sockfd, arr, sizeof(arr)); read(sockfd, rec, SIZE * sizeof(rec)); printf("\nresult from server - rec[]\n"); for (i = 0; i < SIZE; i++) printf("rec[%d] = %d\n", i, rec[i]); close(sockfd); exit(0); }

20170407

課堂練習 (一)

/* Make the necessary includes and set up the variables. */ #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> #include <pthread.h> void *thread_function(void *arg); int main() { int server_sockfd, client_sockfd; int server_len, client_len; struct sockaddr_in server_address; struct sockaddr_in client_address; pthread_t a_thread; void *thread_result; int res; /* Create an unnamed socket for the server. */ server_sockfd = socket(AF_INET, SOCK_STREAM, 0); /* Name the socket. */ server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = inet_addr("127.0.0.1"); server_address.sin_port = 9734; server_len = sizeof(server_address); bind(server_sockfd, (struct sockaddr *)&server_address, server_len); /* Create a connection queue and wait for clients. */ listen(server_sockfd, 5); while(1) { printf("\nServer waiting...\n"); /* Accept a connection. */ client_len = sizeof(client_address); client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, &client_len); res = pthread_create(&a_thread, NULL, thread_function, (void *)(long)client_sockfd); if (res != 0) { perror("Thread creation failed"); exit(EXIT_FAILURE); } } } /* We can now read/write to client on client_sockfd. */ void *thread_function(void *arg) { int i, j, tmp = 0, get_n; int client_sockfd = (long)arg; int *buf; read(client_sockfd, &get_n, sizeof(get_n)); buf = (int *) malloc(get_n * sizeof(int)); read(client_sockfd, buf, get_n * sizeof(int)); printf("sort arr[%d] from client:\n", get_n); for (i = 0; i < get_n; i++) { for (j = 0; j < get_n; j++) { if (buf[i] < buf[j]) { tmp = buf[i]; buf[i] = buf[j]; buf[j] = tmp; } } } for (i = 0; i < get_n; i++) printf("arr[%d] = %d\n", i, buf[i]); // sleep(3); write(client_sockfd, buf, get_n * sizeof(buf)); close(client_sockfd); pthread_detach(pthread_self()); pthread_exit(0); }
/* Make the necessary includes and set up the variables. */ #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> #define SIZE 5 int main() { int sockfd; int len; struct sockaddr_in address; int result, n; /* Create a socket for the client. */ sockfd = socket(AF_INET, SOCK_STREAM, 0); /* Name the socket, as agreed with the server. */ address.sin_family = AF_INET; address.sin_addr.s_addr = inet_addr("127.0.0.1"); address.sin_port = 9734; len = sizeof(address); /* Now connect our socket to the server's socket. */ result = connect(sockfd, (struct sockaddr *)&address, len); if (result == -1) { perror("oops: client!"); exit(1); } /* We can now read/write via sockfd. */ int i, j, tmp = 0, s = SIZE; int arr[SIZE] = {4, 7, 1, 8, 3}; int rec[SIZE] = {0, 0, 0, 0, 0}; printf("%d\n", s); write(sockfd, &s, sizeof(int)); printf("\noriginal from client - arr[]\n"); for (i = 0; i < SIZE; i++) printf("arr[%d] = %d\n", i, arr[i]); write(sockfd, arr, sizeof(arr)); read(sockfd, rec, SIZE * sizeof(rec)); printf("\nresult from server - rec[]\n"); for (i = 0; i < SIZE; i++) printf("rec[%d] = %d\n", i, rec[i]); close(sockfd); exit(0); }

課堂練習 (二)

#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <pthread.h> #include <time.h> #define NUM_THREADS 5 #define MSIZE 10 static double getDoubleTime(); // void check(); void *thread_function(void *arg); // srand(time(NULL)); // int a = (rand() % 10) + 1; int A[MSIZE][MSIZE]; int B[MSIZE][MSIZE]; int C[MSIZE][MSIZE]; int D[MSIZE][MSIZE]; int main(void) { int res; int i, j; srand(time(NULL)); for (i = 0; i < MSIZE; i++) { for (j = 0; j < MSIZE; j++) { A[i][j] = 1; // (rand() % 10) + 1; B[i][j] = 2; // (rand() % 10) + 1; } } pthread_t a_thread[NUM_THREADS]; void *thread_result; int lots_of_threads; double start_time = getDoubleTime(); for (lots_of_threads = 0; lots_of_threads < NUM_THREADS; lots_of_threads++) { res = pthread_create(&(a_thread[lots_of_threads]), NULL, thread_function, (void *)(long)lots_of_threads); if (res != 0) { perror("Thread creation failed"); exit(EXIT_FAILURE); } // sleep(1); } printf("Waiting for threads to finish...\n"); for (lots_of_threads = NUM_THREADS - 1; lots_of_threads >= 0; lots_of_threads--) { res = pthread_join(a_thread[lots_of_threads], &thread_result); if (res == 0) { printf("Picked up a thread[%d]\n", lots_of_threads); } else { perror("pthread_join failed"); } } double finish_time = getDoubleTime(); printf("All done\n"); // check(); printf("Execute Time: %.3lf ms\n", (finish_time - start_time)); exit(EXIT_SUCCESS); } void *thread_function(void *arg) { int my_number = (long)arg; int i, j, k; printf("Thread Number[%d]\n", my_number); for (i = (MSIZE / NUM_THREADS) * my_number; i < ((MSIZE / NUM_THREADS) * my_number) + (MSIZE / NUM_THREADS); i++) { for (j = 0; j < MSIZE; j++) { for (k = 0; k < MSIZE; k++) C[i][j] += A[i][k] * B[k][j]; printf("C[%d][%d]:{%d} = A[%d][%d]:{%d} * B[%d][%d]:{%d}\n", i, j, C[i][j], i, j, A[i][j], i, j, B[i][j]); } } pthread_exit(NULL); } static double getDoubleTime() { struct timeval tm_tv; gettimeofday(&tm_tv, 0); return (double)(((double)tm_tv.tv_sec * (double)1000. + (double)(tm_tv.tv_usec)) * (double)0.001); } /* void check() { int i, j, k; int count = 0; for (i = 0; i < MSIZE; i++) { for (j = 0; j < MSIZE; j++) { for (k = 0; k < MSIZE; j++) D[i][j] += A[i][k] * B[k][j]; } } for (i = 0; i < MSIZE; i++) { for (j = 0; j < MSIZE; j++) { if ((D[i][j] - C[i][j]) != 0) { count++; printf("Error[%d][%d] = [%d]\n", i, j, D[i][j] - C[i][j]); } } } printf("Different = [%d]\n", count); }

20170414

(一) Shared Memory Concept

(二) Shared Memory Function

#include <sys/sem.h> #include <sys/type.h> #include <sys/ipc.h> int shmget(key_t key, size_t size, int shmflg); // 建立 shared memory 。 void *shmat(int shm_id, const void *shm_addr, int shmflg); // 允許程序對 shared memory 存取。 int shmdt(const void *shm_addr); // 讓目前的程序從 shared memory 脫離出來。 int shmctl( int shm_id, int cmd, struct shmid_ds *buf ); // 用來改變 shared memory 。

shmget()

int shmget(key_t key, size_t size, int shmflg);

*shmat()

void *shmat(int shm_id, const void *shm_addr, int shmflg);

shmdt()

int shmdt(const void *shm_addr);

shmctl()

int shmctl(int shm_id, int cmd, struct shmid_ds *buf);
struct shmid_ds {
    uid_t shm_perm.uid;
    uid_t shm_perm.gid;
    mode_t shm_perm.mode;
}

課堂作業

/* vim: ts=4 sw=4 et */ /* The second program is the producer and allows us to enter data for consumers. It's very similar to shm1.c and looks like this. */ #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <time.h> #include <sys/shm.h> #include "shm_com.h" int main() { void *shared_memory = (void *)0; struct shared_use_st *shared_stuff; char buffer[BUFSIZ]; int shmid; int rand_arr[10]; shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666 | IPC_CREAT); if (shmid == -1) { fprintf(stderr, "shmget failed\n"); exit(EXIT_FAILURE); } shared_memory = shmat(shmid, (void *)0, 0); if (shared_memory == (void *)-1) { fprintf(stderr, "shmat failed\n"); exit(EXIT_FAILURE); } printf("Memory attached at %X\n", (unsigned int)(long)shared_memory); shared_stuff = (struct shared_use_st *)shared_memory; /* Initial the array */ for (int i = 0; i < 10; i++) shared_stuff->some_text[i] = 0; shared_stuff->written_by_you = 1; shared_stuff->answer_by_you = 0; while (1) { while (shared_stuff->written_by_you == 1) { sleep(1); printf("Waiting for server...\n"); } printf("\n【Server connected】\n"); /* Generate random number */ printf("Generate random number\n"); srand((unsigned)time(NULL)); for (int i = 0; i < 10; i++) { rand_arr[i] = rand() % 100 + 1; shared_stuff->some_text[i] = rand_arr[i]; } shared_stuff->written_by_you = 2; /* Wait for the sorted array */ printf("Wait for the sorted array...\n"); while (shared_stuff->answer_by_you == 0); printf("The array (After Sorted)\n"); for (int i = 0; i < 10; i++) { printf("[%d]%d \t", i, shared_stuff->some_text[i]); } printf("\n"); shared_stuff->written_by_you = 1; shared_stuff->answer_by_you = 0; break; } if (shmdt(shared_memory) == -1) { fprintf(stderr, "shmdt failed\n"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }
/* vim: ts=4 sw=4 et */ /* Our first program is a consumer. After the headers the shared memory segment (the size of our shared memory structure) is created with a call to shmget, with the IPC_CREAT bit specified. */ #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <sys/shm.h> #include "shm_com.h" int main() { void *shared_memory = (void *)0; struct shared_use_st *shared_stuff; int shmid; srand((unsigned int)getpid()); shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666 | IPC_CREAT); if (shmid == -1) { fprintf(stderr, "shmget failed\n"); exit(EXIT_FAILURE); } /* We now make the shared memory accessible to the program. */ shared_memory = shmat(shmid, (void *)0, 0); if (shared_memory == (void *)-1) { fprintf(stderr, "shmat failed\n"); exit(EXIT_FAILURE); } printf("Memory attached at %X\n", (unsigned int)(long)shared_memory); /* The next portion of the program assigns the shared_memory segment to shared_stuff, which then prints out any text in written_by_you. The loop continues until end is found in written_by_you. The call to sleep forces the consumer to sit in its critical section, which makes the producer wait. */ shared_stuff = (struct shared_use_st *)shared_memory; shared_stuff->written_by_you = 1; while (1) { /* Wait for the client */ if (shared_stuff->written_by_you != 2) shared_stuff->written_by_you = 0; if (shared_stuff->written_by_you == 2) { printf("\n【Get the client's array】\n"); printf("The array (Before Sorted)\n"); for (int i = 0; i < 10; i++) { printf("[%d]%d \t", i, shared_stuff->some_text[i]); } printf("\n"); /* Sort the array */ shared_stuff->answer_by_you = 0; int tmp = 0; for (int i = 0; i < 10; i++) { for (int j = 0; j < 10 ; j++) { if (shared_stuff->some_text[i] < shared_stuff->some_text[j]) { tmp = shared_stuff->some_text[i]; shared_stuff->some_text[i] = shared_stuff->some_text[j]; shared_stuff->some_text[j] = tmp; } } } shared_stuff->answer_by_you = 1; sleep(rand() % 4); /* make the other process wait for us ! */ shared_stuff->written_by_you = 1; } sleep(1); } /* Lastly, the shared memory is detached and then deleted. */ if (shmdt(shared_memory) == -1) { fprintf(stderr, "shmdt failed\n"); exit(EXIT_FAILURE); } if (shmctl(shmid, IPC_RMID, 0) == -1) { fprintf(stderr, "shmctl(IPC_RMID) failed\n"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }

20170428

(一) Low-level file access

Header:#include <unistd.h>

1. open

2. read

#include <unistd.h>

int main()
{
    char buffer[128];
    int nread;
    
    nread = read(0, buffer, 128);
    if (nread == -1)
        write(2, "A read error has occurred\n", 26);

    if ((write(1, buffer, nread)) != nread)
        write(2, "A write error has occurred\n", 27);
        
    exit(0);
}

3. write

#include <unistd.h>

int main()
{
    if ((write(1, "Here is some data\n", 18)) != 18
)
    write(2, "A write error has occurred on file descriptor 1\n",46);

    exit(0);
}

[Example] File copy

#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    char c;
    int in, out;
    
    in = open("file.in", O_RDONLY);
    out = open("file.out", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);

    while(read(in,&c,1) == 1)
        write(out,&c,1);
        
    exit(0);
}
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    char block[1024];
    int in, out;
    int nread;
    
    in = open("file.in", O_RDONLY);
    out = open("file.out", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
    while((nread = read(in,block,sizeof(block))) > 0)
        write(out,block,nread);

    exit(0);
}

(二) Standard I/O Library

Header:#include <stdio.h>

fopen

2. printf, sprintf, fprintf

%d, %o, %x, %c ,%s ,%f (float) ,%e (double) ,%g (double)

3. scanf, fscanf, sscanf

%d, %o, %x, %f, %e, %g, %c, %s, %[] (掃瞄特定字元), %% (掃瞄 % 的字元)

20170505

(一) mmap

(二) msync

(三) munmap

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 100
int main() {

	FILE *fptr, *fptr2;
	int i, j;
	float a, b;
    srand(time(NULL));

	fptr = fopen("ans.txt", "w");

	if (!fptr){
		printf("open error \n");
		exit(1);
	} else {
        printf("open success, start writing into file\n");
    }

	for (i = 1; i <= SIZE; i++) {
        a = ((float)rand() / (float)(RAND_MAX)) * 100;
		printf("[%3d] = %3.3f\n", i, a);
		fprintf(fptr, "%3.3f\n", a);
	}

	fclose(fptr);
	/*---------------------------------------------------------- */
	fptr2 = fopen("ans.txt", "r");

	if(!fptr2) {
		printf("open error\n");
		exit(1);
	} else {
	    printf("open success, start reading from file\n");
	}

	i = 1;
	while (fscanf(fptr2, "%6f" ,&b) == 1)
		printf("[%3d] = %3.3f\n", i++, b);
	
	fclose(fptr2);
	return 0;
}

課堂作業

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define SIZE 100
int main() {

	FILE *fptr1, *fptr2;
	int i;
	float a = .0, total = .0, avg = .0;
    float sigma = .0, sd = .0;


    /* Use fptr1 to calculate total and average */
    fptr1 = fopen("ans.txt", "r");
	if (!fptr1) {
		printf("open error\n");
		exit(1);
	} 
    
    else {
	    printf("\nopen success, fptr1 starts reading from file\n");
	}


    i = 1;
    while (fscanf(fptr1, "%6f" ,&a) == 1) {
		printf("[%3d] = %3.3f\n", i++, a);
        total += a;
    }
	avg = (total / i);
    fclose(fptr1);




    /* Use fptr2 to calculate standard deviation */
    fptr2 = fopen("ans.txt", "r");
    if (!fptr2) {
		printf("open error\n");
		exit(1);
	} 
    
    else {
	    printf("\nopen success, fptr2 starts reading from file\n");
	}


    i = 1;
    while (fscanf(fptr2, "%6f" ,&a) == 1) {
        sigma += (a - avg) * (a - avg);
        i++;
    }
    sd = sqrt(sigma / i); 
    fclose(fptr2);




    /* Output */
    printf("\n\nThe average = %f\n", avg);
    printf("The standard deviation = %f\n", sd);


	return 0;
}

20170512

(一) Shell 簡介

(二) 變數 (variables)

#!/bin/sh
salutation=Hello
echo $salutation

salutation="Yes Dear"
echo $salutation

salutation=7+5
echo $salutation

(三) 引號 (quoting)

#!/bin/sh
myvar="Hi there"

echo $myvar
echo "$myvar"
echo '$myvar'
echo \$myvar

echo "Please enter something..."
read myvar
echo $myvar

(四) 條件判斷 (condition)


(五) 控制結構 - if

#!/bin/sh
echo "Is it morning ?"
read timeofday

if [ $timeofday = "yes" ]; then
    echo "Good morning"
else
    echo "Good afternoon"
fi

(六) 控制結構 - elif

#!/bin/sh
echo "Is it morning ?"
read timeofday

if [ "$timeofday" = "yes" ]
then
    echo "Good morning"

elif [ "$timeofday" = "no" ]; then
    echo "Good afternoon"

else
    echo "Sorry, $timeofday not recognized"
fi

(七) 控制結構 - for

Example 1
#!/bin/sh
for foo in bar fud 43
do
echo $foo
done
Example 2
#!/bin/sh
for i in 1 2 3
do
echo $i
done

(八) 控制結構 - while

Example 1
#!/bin/sh
echo "Enter password"
read trythis
    
while [ "$trythis" != "secret" ]; do
    echo "Sorry, try again"
    read trythis
done
Example 2
#!/bin/sh
foo=1

while [ "$foo" -le 20 ]
do
    echo "Here we go again"
    foo=$(($foo+1))
done
exit 0
Example 3
#!/bin/sh
x=0

while [ "$x" -ne 10 ]; do
    echo $x
    x=$(($x+1))
done
exit 0

(九) 控制結構 - case

Example 1
#!/bin/sh
echo "Is it morning? Please answer 'Yes'、'y'、'No'、'n'"
read timeofday

case "$timeofday" in
	Yes) echo "Good Morning" ;;
	No) echo "Good Aftrenoon" ;;
	y) echo "Good Morning" ;;
	n) echo "Good Aftrenoon" ;;
	*) echo "Sorry, answer not recognized" ;;
esac
Example 2
#!/bin/sh
echo "Is it morning? Please answer 'Yes'、'Y...'、'y'、'No'、'N...'、'n'"
read timeofday

case "$timeofday" in
    Y* | y | Yes) echo "Good Morning" ;;
    N* | n | No) echo "Good Aftrenoon" ;;
    *) echo "Sorry, answer not recognized" ;;
esac

(十) 控制結構 - AND

Example 1
#!/bin/sh
touch file_one
rm file_two

if [ -f file_one ] && echo "hello" && [ -f file_two ] && echo "there"
then 
    echo "in if"
else
    echo "in else"
fi

exit 0

(十一) 控制結構 - OR

Example 1
#!/bin/sh
rm –f file_one

if [ -f file_one ] || echo "hello" || echo "there"
then
    echo "in if"
else
    echo "in else"
fi

exit 0

課堂作業

20170519

(一) 函數 (Function)

#!/bin/sh

foo() {
    echo "Function foo is excuting"
}

echo "Script starting"
foo
echo "Script ending"

(二) 命令 (command)

Example 1
#!/bin/sh

for x in 1 2 3
do 
    echo before $x
    continue
    echo after $x
done
Example 2
#!/bin/sh

for x in 1 2 3
do 
    echo before $x
    break
    echo after $x
done

其他命令

(三) 命令 (command) - find

-atime N           檔案最後存取時間是 N 天以前
-mtime N           檔案最後修改時間是 N 天以前
-newer otherfle    檔案比 otherfle 還要新
-name pattern      搜尋 pattern 名稱的檔案
-type C            檔案型態是 C 的檔案
-user username     檔案為 username 使用者所擁有

find / -name test -print
find . -newer test -print

(四) 命令 (command) - grep

-c    不印出吻合的那一行,只印出吻合的數量
-E    開啟延伸表示式
-h    輸出的結果不顯示檔案名稱
-I    忽略大小寫
-l    只列出檔案名稱
-v    反向比對,排除吻合樣本的結果

grep in word.txt
grep -c in word.txt word2.txt

正規表示式


20170526