Linux 系統與程式設計
程式作業: fork()
的概念
#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);
}
}
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;
}
kill -signal pid
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?) */
#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);
}
}
#include <signal.h>
int sigaction(int sig,const struct sigaction *act, struct sigaction *oact);
參數說明
程式作業:signal
的處理
#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);
}
}
self-contained domain (protection)
and execution of instructions
.
Thread management
: create, terminate, join, and detachMutexes
: mutual exclusion, creating, destroying, locking, and unlocking mutexesCondition variables
: event driven synchronizaiton.gcc aaa.c -o aaa -lpthread
Creation
Termination
Wait (parent/child synchronization)
找出 1 - 100 的所有質數
#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);
}
#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
int pthread_create(pthread_t *thread,
pthread_attr_t *attr, void *(*start_routine)(void
*), void *arg);
pthread_t *thread
:thread 的識別字pthread_attr_t *attr
:thread 的屬性,設定為 NULL 表示使用預設值void *(*start_routine)(void*)
:thread 要執行的 functionvoid *arg
:傳遞給 thread 的參數void pthread_exit(void *retval);
void *retval
:thread 結束時回傳的變數int pthread_join(pthread_t th, void **thread_return);
pthread_t th
:thread 識別字void **thread_return
:接收 pthread_exit 傳回的變數int pthread_setcancelstate(int state, int *oldstate);
int state
:設定為 PTHREAD_CANCEL_ENABLE 即表示允許取消 thread 的請求;設定為 PTHREAD_CANCEL_DISABLE 即表示忽略取消的請求。int *oldstate
:此指標指向前一個狀態int pthread_setcanceltype(int type, int *oldtype);
int type
:設定為 PTHREAD_CANCEL_ASYNCHRONOUS 則立即取消 thread;設定為 PTHREAD_CANCEL_DEFERRED 則會遇到取消點才會取消 thread。
pthread_join
、pthread_cond_wait
、pthread_testcancel
…等int *oldtype
:此指標指向前一個型態。#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
int sem_init(sem_t *sem, int pshared, unsigned
int value);
sem_t *sem
:semaphore 識別字int pshared
:設定為 0 表示僅供目前的 process 及其 thread 使用。非 0 表示此 semaphore 與其他 process 共用unsigned int value
:semaphore 的初始值int sem_wait(sem_t *sem);
int sem_post(sem_t *sem);
int sem_destroy(sem_t *sem);
//delete a semaphore
#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
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
pthread_mutex_t *mutex
:mutex 識別字const pthread_mutexattr_t *mutexattr
:mutex 的屬性。設定為 NULL 表示使用預設。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
/*
* 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 */
}
An interface between application and network.
reliable
vs. best effort
connection-oriented
vs. connectionless
Once configured the application can
server
部份
/* 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);
}
}
client
部份
/* 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);
}
利用Socket Programming,將 client 端的整數陣列傳送給 server 端排序,並將排序後的結果回傳給 client 端顯示。
server
部份
/* 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);
}
}
client
部份
/* 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);
}
將 Socket 以 multithread 的方式執行:
Server
部份
/* 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);
}
Client
部份
/* 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);
}
#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 。
int shmget(key_t key, size_t size, int shmflg);
void *shmat(int shm_id, const void *shm_addr, int shmflg);
int shmdt(const void *shm_addr);
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;
}
client
部份
/* 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);
}
server
部份
/* 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);
}
Header:#include <unistd.h>
Action
Status
Permission
int open(const char* path, int oflags);
int open(const char* path, int oflags, mode_t mode);
size_t read(int fildes, void* buf, size_t nbytes);
#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);
}
size_t write(int fildes, void* buf, size_t n bytes);
#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);
}
#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);
}
Header:#include <stdio.h>
fopen
, fclose
fread
, fwrite
fflush
fseek
fgetc
, getc
, getchar
fputc
, putc
, putchar
fgets
, gets
printf
, fprintf
, sprintf
scanf
, fscanf
, sscanf
FILE *fopen(const char *filename, const char* mode);
r
(唯讀模式)w
(寫入模式、長度歸零)a
(寫入模式、附加)%d, %o, %x, %c ,%s ,%f (float) ,%e (double) ,%g (double)
%d, %o, %x, %f, %e, %g, %c, %s, %[] (掃瞄特定字元), %% (掃瞄 % 的字元)
void *mmap(void *addr, size_t len, int port, int flags, int fildes, off_t off);
int msync(void* addr, size_t len, int flags);
int munmap(void * addr, size_t len);
fprintf.c
#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;
}
#!/bin/sh
salutation=Hello
echo $salutation
salutation="Yes Dear"
echo $salutation
salutation=7+5
echo $salutation
#!/bin/sh
myvar="Hi there"
echo $myvar
echo "$myvar"
echo '$myvar'
echo \$myvar
echo "Please enter something..."
read myvar
echo $myvar
#!/bin/sh
echo "Is it morning ?"
read timeofday
if [ $timeofday = "yes" ]; then
echo "Good morning"
else
echo "Good afternoon"
fi
#!/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
#!/bin/sh
for foo in bar fud 43
do
echo $foo
done
#!/bin/sh
for i in 1 2 3
do
echo $i
done
#!/bin/sh
echo "Enter password"
read trythis
while [ "$trythis" != "secret" ]; do
echo "Sorry, try again"
read trythis
done
#!/bin/sh
foo=1
while [ "$foo" -le 20 ]
do
echo "Here we go again"
foo=$(($foo+1))
done
exit 0
#!/bin/sh
x=0
while [ "$x" -ne 10 ]; do
echo $x
x=$(($x+1))
done
exit 0
#!/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
#!/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
#!/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
#!/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
#!/bin/sh
foo() {
echo "Function foo is excuting"
}
echo "Script starting"
foo
echo "Script ending"
#!/bin/sh
for x in 1 2 3
do
echo before $x
continue
echo after $x
done
#!/bin/sh
for x in 1 2 3
do
echo before $x
break
echo after $x
done
-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
-c 不印出吻合的那一行,只印出吻合的數量
-E 開啟延伸表示式
-h 輸出的結果不顯示檔案名稱
-I 忽略大小寫
-l 只列出檔案名稱
-v 反向比對,排除吻合樣本的結果
grep in word.txt
grep -c in word.txt word2.txt