管理多线程应用程序中的共享变量 [英] Manage shared variable in multithreading application

查看:96
本文介绍了管理多线程应用程序中的共享变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我设计了一个示例多线程应用程序,其中我使用循环缓冲区在一个线程中读取一个文件,并且检查是否满足还是不将相同的缓冲区写入带有检查缓冲区isEmpty的输出文件。所以问题是第一个线程完成它首先执行所以第二个线程在缓冲区中获取剩余数据,因此输出错误。我粘贴我的应用程序代码,请检查它&建议任何共享缓冲区访问的解决方案。

I design one sample multithreaded application in which i read one file in one thread using circular buffer with checking isfull or not also write same buffer to output file with checking buffer isEmpty or not.So problem is that first thread complete it's execution first so that second thread gets remaining data in buffer,so output is wrong.Below i paste code of mine application,please check it & suggest any solution for shared buffer accessing.

 /* Circular Queues */

#include <iostream>
using namespace std;
#include<windows.h>

const int chunk = 512;		//buffer read data 
const int MAX = 2*chunk ;	//queue size
unsigned int Size ;
FILE *fpOut;
FILE *fp=fopen("Test_1K.txt","rb");

//class queue 
class cqueue
{
	public :
		static int front,rear;
		static char *a;
	   cqueue()
	   {
		 front=rear=-1;
		 a=new char[MAX];
	   }
	   ~cqueue()
	   {
		delete[] a;
	   }
};

int cqueue::front;
int cqueue::rear;
char* cqueue::a;

DWORD WINAPI Thread1(LPVOID param)
{	
	int i;

	fseek(fp,0,SEEK_END);
	Size=ftell(fp);				//Read file size
	cout<<"\nsize is"<<Size;
	rewind(fp);

 	for(i=0;i<Size;i+=chunk)	//read data in chunk as buffer half size 
	{
		while((cqueue::rear==MAX-1)); //wait until buffer is full?
			if((cqueue::rear>MAX-1))		
			  cqueue::rear=0;		
		   else{
			   fread(cqueue::a,1,chunk,fp);	//read data from in buffer
 			    cqueue::rear+=chunk;		//increment rear pointer of queue to indicate buffer is filled up with data
				 if((cqueue::front==-1))	
					cqueue::front=0;		//update front pointer value to read data from buffer in Thread2
		   } 
	}
	fclose(fp);
	cout<<"\nQueue write completed\n";
    return 0;
}
DWORD WINAPI Thread2(LPVOID param)
{
	for(int j=0;j<Size;j+=chunk)
	{
		while((cqueue::front==-1)); //wait until buffer is empty
		cqueue::front+=chunk;		//update front pointer after read data from queue
		fwrite(cqueue::a,1,chunk,fpOut);	//write data file
		
	   if((cqueue::front==MAX-1))
		  cqueue::front=0;		//update queue front pointer when it reads upto queue Max size
	}
	fclose(fpOut);
	cout<<"\nQueue read completed\n";
	return 0;
}


void startThreads()
{
    DWORD  threadIDs[2];
	HANDLE threads[2];	
	fpOut=fopen("V-1.7OutFile.txt","wb");
    threads[0] = CreateThread(NULL,0,Thread1,NULL,0,&threadIDs[0]);
    threads[1] = CreateThread(NULL,0,Thread2,NULL,0,&threadIDs[1]);	
	
    if(threads[0] && threads[1])
    {
        printf("Threads Created.(IDs %d and %d)",threadIDs[0],threadIDs[1]);
    }
}

void main()
{
	 cqueue c1;
	 startThreads();
	 system("pause");
}

推荐答案

共享内存是一个更好的解决方案,因为您可以避免磁盘访问及其问题。



尝试一下:



http://msdn.microsoft.com/en-us/library/windows/desktop/aa366551(v = vs.85)的.aspx [ ^ ]



PS:在应用程序目录中写一个文件总是一个坏主意
Shared memory is a better solution, because you avoid disk access and its problems.

try it out:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366551(v=vs.85).aspx[^]

PS: writing a file in the directory of the app is always a bad idea


您描述了经典的制作人 - 消费者问题。



[ ] http://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem [ ^ ]



关于你实现的队列 - 更好的解决方案是将队列操作封装在队列类中,并使内部队列数据保密。



另一种选择 - 只需使用<队列> STL。
You describe classic Producer-Consumer problem.

[]http://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem[^]

Regarding queue that you implemented - much better solution is to encapsulate queue operations in the queue class, and make internal queue data private.

Another option - just use < queue > STL.


除了在其他解决方案中所说的内容之外,您还需要使用一些同步机制(锁,信号量,互斥锁)或并发容器或一些无锁容器。 />


特别是
In addition to what has been said in other solutions, you need to use some synchronisation mechanism (lock, semaphore, mutex) or concurrent containers or some lock-free container.

In particular, the line
while((cqueue::front==-1)); //wait until buffer is empty

非常糟糕,因为它会导致繁忙的等待这对一般性能或电池持续时间都不利。



鉴于您似乎对线程一无所知,最好先阅读一些教程。这...否则你的程序将无法正常工作。



MSDN文档有很多相关信息。以下页面概述了Win32 API级别的可用功能: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686360(v = vs.85).aspx [ ^ ]



您可以使用信号量来解决问题(循环缓冲区)或某些锁定以及更多逻辑。



无论如何,你想要使用等待功能( http:// msdn。 microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx [ ^ ])作为示例,以便CPU可以免费供其他程序使用,直到一些数据准备就绪。



Als o在 cqueue 类中,该成员都不应该是静态的,否则您不能多次使用该类。您的代码还有许多其他问题。阅读一些书来帮助你制作更强大的程序可能是一个好主意。

is really bad because it cause busy waiting which is bad for general performance or battery duration.

Given that it seems that you know nothing about threading, it would be a good idea for you to read some tutorial on this... otherwise your program won't works correctly.

MSDN documentation have a lot of information about that. The following page give you an overview of available functions at the Win32 API level: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686360(v=vs.85).aspx[^]

You can use a semaphore for you problem (circular buffer) or some lock and a bit more logic.

In any case, you want to use a wait function (http://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx[^]) as an example so that the CPU will be free for use by other programs until some data is ready.

Also in your cqueue class, none of the member should be static as otherwise you cannot use that class more than once. And there are many other problem with your code. It might be a good idea to read some books to help you make more robust programs.


这篇关于管理多线程应用程序中的共享变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆