Linux 多線程文件讀寫操作 +實例


郵箱通訊

 聲明以下全局變量

char cBuff[256];   //郵箱

int iHead;        //郵箱頭指針

int iTail;        //郵箱尾指針

 

創建兩個線程:XXX_Write和XXX_Read。

XXX_Write:讀取一個文件(大點的),將文件內容按序寫入郵箱,同時修改尾指針。即頭尾指針之間的內容是提供給XXX_Read線程讀取的。

XXX_Read:從郵箱中讀取未讀的數據,寫入一個新文件,同時修改頭指針。


#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>




#define MAX 256     /* 郵箱大小*/
#define SIZE 99		/*每次讀取長度範圍 小於郵箱大小*/


char cBuff[MAX];	/*郵箱*/
int iHead;			/*頭指針*/
int iTail;			/*尾指針*/


int jiangmq_read(const char *w_path)
{
	FILE *w_fp;	
	int sizen;  	/*實際讀入的大小*/	


	if(NULL == (w_fp= fopen(w_path , "r")))
	{
			printf("error: Can not open %s .\n",w_path);
			
			pthread_exit((void *)1);
	}
	
	
	while(1)
	{


		/*判斷郵箱是否已寫滿了*/
		if((iTail < iHead) && (iTail > (iHead -SIZE)))   
		{
			continue ;
		}


		/*讀取數據到郵箱中*/
		if((sizen = fread(cBuff+iTail,1,SIZE,w_fp)) == 0 )  
		{
				while(1)
				{
					if(iHead == iTail)
					{	
						fclose(w_fp);
						pthread_exit((void *)1);
					}
				}
		}


		/*寫完一次郵箱 移動尾指針*/
		iTail += sizen;				
		
		
		/*再次判斷郵箱是否 將要 寫滿*/
		while((iHead == (iTail+sizen))||(((MAX - iTail) < SIZE)&&(iHead <= SIZE))){}




		/*判斷是否到郵箱尾部*/
		if((MAX - iTail) < SIZE)
				{					
					iTail = 0;			
				}




	}
}






int jiangmq_write(const char *r_path)
{
    
	FILE *fp;
	int sizen;	/*實際讀取的大小*/
	int tmp ; 	/*標示實際要讀取內容的大小*/
	
	if(NULL == (fp = fopen(r_path , "w")))
	{
			printf("error: Can not open %s.\n",r_path);
			
			pthread_exit((void *)1);
	}


	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);	
	
	
	while(1)
	{


		/*判斷郵箱是否爲空*/
		if((iHead == iTail) ) 
		{
			continue ;
		}
		


		tmp=SIZE;


		/*當郵箱中可讀內容不足標準大小*/
		if((iTail > iHead)&&((iTail-SIZE) < iHead))
		{
			p = iTail-iHead;
			
		}




		/*把郵箱中內容寫入文件中*/
		if((sizen = fwrite(cBuff+iHead,1, tmp,fp)) < 0) 
		{
			fclose(fp);
			
			pthread_exit((void *)2);
		}
		


		/*讀完郵箱一次 移動頭指針*/
		iHead += sizen ; 




		/*判斷是否到郵箱尾部*/
		if(iHead > (MAX - SIZE))
		{
				while(iTail == iHead){}
				
				iHead = 0;
		}
		
	
		
		
	}
}




int main(int argc , char *argv[])
{
	int *value_ptr;
    pthread_t wtid,rtid;
	


	/*初始化頭尾指針*/
	iHead = 0; 
	iTail = 0;




	if(argc != 3)
	{
			printf("error:please input two files name.\n");
			return -1;
	}
	
	if(pthread_create(&rtid,NULL,(void *)jiangmq_write,argv[2]) != 0)
	{
			printf("error: Can not create jiangmq_write.\n");
			return -2;
	}
	


	if(pthread_create(&wtid,NULL,(void *)jiangmq_read,argv[1]) != 0)
	{
			printf("error: Can not create jiangmq_read.\n");
			return -2;
	}


	/*等待線程讀入結束*/	
	pthread_join(wtid,(void **)&value_ptr); 
	
	/*終止寫出線程*/
	pthread_cancel(rtid);


	printf(" over \n");
		
	return 0;
}

改進的全雙工通信代碼下載地址

http://download.csdn.net/detail/jmq_0000/4093546

用兩個進程間分別又有兩個線程通過共享內存操作

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章