網頁

2012年11月23日 星期五




作業系統功課

ARM CPU也可以運行的

題目:

使用Linux以共享記憶體做兩process之溝通
  1. A程式接受user輸入英文word,然後將英文word存入共享記憶體
  2. B程式從share memory陸續讀出英文word,並且將它們排序,及統計出現次數
  3. 當A程式存入特殊字元'#'至共享記憶體時,B程式要把目前收集的英文word依序排序結果(包含次數資料輸出)
(共享記憶體只是作為 溝通與傳遞資料 之用,所以僅需要容納 一個word的空間和儲存幾個同步用的變數、英文word排序結果是根據英文字母的順序)
繳交期限 :   2012/11/23(五)
繳交內容 :  程式執行碼 & 說明文件(也可以直接寫在程式碼內)

My answer:
可以參考書第3章

因為沒有使用有C++,全部使用沒有物件導向功能的ANSI C語法,所以有很長的程式碼都是在寫link-list。

我的Server部分程式碼:
#include <stdio.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#define size 140

struct packet_data {
    char data[size];
    short locked;
};
struct data_list {    //store the string
    char data[size];
    int count;
    struct data_list *next;
};

int main(void) {
    struct packet_data *shared_memory;
    struct data_list *first=NULL,*previous,*current,*new_data;
    int segment_id;
    segment_id = shmget(IPC_PRIVATE, sizeof(struct packet_data), S_IRUSR | S_IWUSR);  //allocate a shared memory segment
    shared_memory = (struct packet_data*) shmat(segment_id, NULL, 0);  //attach the shared memory segment
    shared_memory->locked = 0;
    printf("Segment_id: %d\n(Copy it to the client program)\n", segment_id);

    while (1) {
        if (shared_memory->locked) {
            if(!strcmp(shared_memory->data,"exit")) {        //exit
                shmdt(shared_memory);    //now detach the shared memory segment
                shmctl(segment_id, IPC_RMID, NULL);    //now remove the shared memory segment
                return 0;
            } else if (!strcmp(shared_memory->data,"#")) {    //#
                printf("\n\nWord counts:\n");
                current=first;
                while (current!=NULL) {
                    printf("%s: %d\n",current->data,current->count);
                    current=current->next;
                }
            }else{
                printf("%s ",shared_memory->data);
                fflush(stdout);
                new_data=(struct data_list*) malloc(sizeof(struct data_list));
                strcpy(new_data->data,shared_memory->data);
                new_data->count=1;
                new_data->next=NULL;
                if (first==NULL)
                    first=new_data;
                else if (strcmp(shared_memory->data,first->data)<0) {
                //if it's smaller than first node
                    new_data->next=first;
                    first=new_data;
                } else {
                    current=previous=first;
                    while (current!=NULL)    //search until the end
                        if (strcmp(shared_memory->data,current->data)>0) {
                            previous=current;
                            current=previous->next;
                        } else break;
                    if (current==NULL) //shared_memory->data is the biggest
                        previous->next=new_data;
                    else if (strcmp(shared_memory->data,current->data)==0) {    //On the list
                        current->count+=1;
                        free(new_data);
                    } else {    //Not found, add to the list in order
                        new_data->next=previous->next;
                        previous->next=new_data;
                    }
                }
            }
            shared_memory->locked=0;
        }
        system("sleep 0.1");    //save battery, you can remove it
    }
    return 0;
}
//u.livekn.com    2012/11/22

Client部分程式碼:
#include <stdio.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#define size 140    //The size of shared memory segment (in byte)

struct packet_data {
    char data[size];
    short locked;
};
    
int main(void) {
    int segment_id;    //The identifier for the shared memory segment
    struct packet_data *shared_memory;
    char user_input[size];
    
    printf("Enter the segment_id: ");
    scanf(" %d",&segment_id);
    shared_memory = (struct packet_data*) shmat(segment_id, NULL, 0);    //attach the shared memory segment
    printf("Type someting:\n");
    
    while(1) {
        if (!shared_memory->locked) {
            scanf(" %140s",user_input);
            strncpy(shared_memory->data,user_input,size);
            shared_memory->locked =1;
            system("sleep 0.5");    //save battery
        }
        if (!strcmp(user_input,"exit"))    //break the loop when user input "exit"
            break;
    }
    shmdt(shared_memory);    //detach the shared memory segment
    return 0;
}
//u.livekn.com    2012/11/22

使用方法:
  1. 運行server
  2. 運行client
  3. 把server顯示的Segment_id複制到client上
  4. 在client輸入文字,server會自動顯示
  5. 在client輸入#,server會顯示各字出現次數
  6. 在client輸入exit,自動結束

已編譯版本:
  1. ARM
  2. i386

沒有留言:

張貼留言