头文件
*/
#define SRCPATH "srcpath/"
#define DSTPATH "dstpath/"
int movefile()
{
DIR *dir
struct dirent *dt
FILE *fp1,*fp2
char filename1[256],filename2[256]
char buf[1024]
int readsize,writesize
if((dir = opendir(SRCPATH)) == NULL)
{
printf("opendir %s error\n",SRCPATH)
return -1
}
memset(filename1,0,sizeof(filename1))
strcpy(filename1,SRCPATH)
memset(filename2,0,sizeof(filename2))
strcpy(filename2,DSTPATH)
while(1)
{
while((dt = readdir(dir)) != NULL)
{
if(strcmp(dt->d_name,".")==0||strcmp(dt->d_name,"..")==0)
{
continue
}
//如果这个目录里 还有目码孝录,可以在这加判断悔模枣
//这碧拆里假设初始为空目录
strcat(filename1,dt->d_name)
strcat(filename2,dt->d_name)
//如果进程资源较少可以直接用linux系统命令
fp1 = fopen(filename1,"rb")
if(fp1==NULL)
{
printf("open %s failed /n",filename1)
return -1
}
fp2 = fopen(filename2,"wb")
if(fp2==NULL)
{
printf("open %s failed /n",filename2)
fclose(fp1)
return -1
}
while((readsize = fread(buf,sizeof(buf),1,fp1))>0)
{
//total += readsize
memset(buf,0,sizeof(buf))
writesize = fwrite(buf,sizeof(buf),1,fp2)
if(writesize!==readsize)
{
printf("write error")
return -2
fclose(fp1)
fclose(fp2)
}
}
fclose(fp1)
fclose(fp2)
rmdir(filename2)
}
}
}
int main(int argc,char **argv)
{
pthread_t id1
int ret
ret = pthread_create(&id1, NULL, (void*)movefile, NULL)
return ret
}
自己调试下
using Systemusing System.Threading
using System.IO
namespace CopyTest
{
//FileBuffer用来存放和取出缓冲区变量
public class FileBuffer
{
private int m_readsize = 1024
//定义了m_capacity个字节的缓冲区
private byte[] m_buffer = new byte[4096]
//确认缓冲区内已放字节的个数
private int bufferCount = 0
//确定读蔽昌写的位置
private int readLocation = 0, writeLocation = 0
public FileBuffer()
{
}
/大消/从缓冲区中取数据
public byte[] getBuffer()
{
//加上了共享锁
lock (this)
{
//判断如果缓冲区内无内容,则读取者进入wait状态,并且释放对象锁
if (bufferCount == 0)
{
Console.WriteLine("缓冲区无数据,无法读取")
Monitor.Wait(this)
}
byte[] newBuf = new byte[m_readsize]
Buffer.BlockCopy(m_buffer, readLocation, newBuf, 0, m_readsize)
//已经从缓冲区读取了内容,所以bufferCount要进行自减.
bufferCount -= m_readsize
//求余的目的是为了循环使用缓冲区
readLocation = (readLocation + m_readsize) % m_buffer.Length
//通知对象的第一个等待线宏仿扒程可以从WaitSleepJoin转换到Started状态.
Monitor.Pulse(this)
//返回给读取者取出的数值
return newBuf
}
}
//将数据放入缓冲区
public void setBuffer(byte[] writeValue)
{
//锁住共享数据区
lock (this)
{
//如果缓冲区已满,那么进入waitsleepjoin状态
if (bufferCount == m_buffer.Length)
{
Console.WriteLine("缓冲区溢出!")
Monitor.Wait(this)
}
//向缓冲区写入数据
Buffer.BlockCopy(writeValue, 0, m_buffer, writeLocation, m_readsize)
//自加,代表缓冲区现在到底有几个数据
bufferCount += m_readsize
//用%实现缓冲区的循环利用
writeLocation = (writeLocation + m_readsize) % m_buffer.Length
//唤醒waitSleepJoin状态的进程,到started状态
Monitor.Pulse(this)
}//使用lock隐式的释放了共享锁
}
}
//写入者类,向缓冲区中放入数据
public class Writer
{
//定义了同步变量
FileBuffer shared
FileStream file
//此处构造函数的作用是在启动类中调用写入者的时候,把启动类中定义的sharedLocation传过来
public Writer(FileBuffer sharedLocation)
{
file = new FileStream("C:\\Test.txt", FileMode.Open)
shared = sharedLocation
}
//定义写入过程
public void Write()
{
//将数据放入缓冲区
Byte[] datas = new byte[1024]
for (int byteread = 0byteread <= file.Lengthbyteread += datas.Length)
{
file.Read(datas, byteread, datas.Length)
shared.setBuffer(datas)
}
file.Close()
//得到当前线程的名字
string name = Thread.CurrentThread.Name
//此线程执行完毕
Console.WriteLine(name + "done writeing")
}
}
public class Reader
{//定义读取者
byte[] value
FileStream file
//定义同步变量
FileBuffer shared
//定义构造函数,负责传递启动类中的shared
public Reader(FileBuffer sharedLocation)
{
file = new FileStream("C:\\Data.txt", FileMode.Create)
shared = sharedLocation
}
public void Read()
{
//从缓冲区中循环读取
for (int bytewrite = 0bytewrite <= 65535)
{
value = shared.getBuffer()
file.Write(value, bytewrite, value.Length)
bytewrite += value.Length
}
file.Close()
//取得当前线程的名字
string name = Thread.CurrentThread.Name
Console.WriteLine(name + "done reading")
}
}
public class ThreadTest
{ //设置为启动类
public static void Main()
{
FileBuffer shared = new FileBuffer()
//初始化了写入者和读取者,并且把shared参数传递了过去
Writer Writer1 = new Writer(shared)
Reader Reader1 = new Reader(shared)
Thread WriterThread = new Thread(new ThreadStart(Writer1.Write))
WriterThread.Name = "写入者"
Thread ReaderThread = new Thread(new ThreadStart(Reader1.Read))
ReaderThread.Name = "读取者"
//启动这两个线程
WriterThread.Start()
ReaderThread.Start()
WriterThread.Join()
ReaderThread.Join()
Console.ReadLine()
}
}
}
主线程读的是A文件,次线程写的是B文件,两者不冲突。4K的buffer已经算很小了。重点是主次线程共享的数据需要做同步,毕祥所以才造成樱侍了要等待的手颂搏现象。你说的类似消费者和生产者模型。欢迎分享,转载请注明来源:内存溢出
评论列表(0条)