1. 程式人生 > >OS實驗二 執行緒同步與通訊

OS實驗二 執行緒同步與通訊

1 實驗目的與要求

1、掌握Linux下執行緒的概念;

2、瞭解Linux執行緒同步與通訊的主要機制;

3、通過訊號燈操作實現執行緒間的同步與互斥。

2 實驗內容

通過Linux多執行緒與訊號燈機制,設計並實現計算機執行緒與I/O執行緒共享緩衝區的同步與通訊。

程式要求:兩個執行緒,共享公共變數a

執行緒1負責計算(1到100的累加,每次加一個數)

執行緒2負責列印(輸出累加的中間結果)

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <pthread.h>

union semun {
    int val; /* value for SETVAL */
    struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
    unsigned short *array; /* array for GETALL, SETALL */
    struct seminfo *__buf; /* buffer for IPC_INFO */
};

int i=0,sum=0;
int semid;//訊號量集合首地址
pthread_t p1,p2;
union semun arg;
void P(int semid, int index);
void V(int semid, int index);
/***對訊號量陣列index編號的訊號量做P操作***/
void P(int semid, int index){
	struct sembuf sem={index,-1,0};
    semop(semid,&sem,1);
}

/***對訊號量陣列index編號的訊號量做V操作***/
void V(int semid, int index){
    struct sembuf sem={index,+1,0};
    semop(semid,&sem,1);
}

/*執行緒一*/      
void thread_1(void){  
    for(;i<=100;i++){ 
    P(semid,0);   
    printf("This is a pthread_1.\ni=%d\n",i);  
    sum+=i;
    V(semid,1); 
    }
	return;  
}  
      
/*執行緒二*/  
void thread_2(void){    
    for(;;){
    P(semid,1); 
    printf("This is a pthread_2.\nsum=%d\n",sum); 
    if(i==101)return;
    V(semid,0);
    }
}  


int main(){
	int key ;
    int ret;
	key=ftok("/tmp", 0x66 ) ;
    if(key<0){
        perror("ftok key error") ;
        return -1 ;
    }
    /***建立兩個訊號量***/
    semid=semget(key,2,IPC_CREAT|0666);
    if(semid==-1){
         perror("create semget error");
         return ;
    }
    /***對0號訊號量設定初始值***/
	arg.val=1;
    ret=semctl(semid,0,SETVAL,arg);//訊號量semid【0】為1
	arg.val=0;
	ret =semctl(semid,1,SETVAL,arg);//訊號量semid【1】為0
    if (ret < 0 ){
        perror("ctl sem error");
        semctl(semid,0,IPC_RMID,arg);
        return -1 ;
    }
    /*建立執行緒一*/  
    ret=pthread_create(&p1,NULL,(void  *) thread_1,NULL);  
    if(ret!=0)  {  
        printf("Create pthread error!\n");  
        return -1;  
    }  
    /*建立執行緒二*/  
     ret=pthread_create(&p2,NULL,(void  *) thread_2,NULL);  
    if(ret!=0)  {  
        printf("Create pthread error!\n");  
        return -1;  
    }  
    /*等待執行緒結束*/  
    pthread_join(p1,NULL);  
    pthread_join(p2,NULL);  
    /***刪除訊號量***/
    semctl(semid,0,IPC_RMID,arg);
    semctl(semid,1,IPC_RMID,arg);
    return 0;  
}

執行結果: