It is happening something that I can not understand. When I run a function which injects 100 pulses (using external electronics...) from my main program it works properly but When I do the same using a function like (thread function):
DWORD WINAPI ThreadClass::ThreadFunc(LPVOID pvParam)
It goes crazy and injects less that what I expect. I have realized that it has something to do with time...because when I write Sleep(10) for example, it works better !!
Ok, The program is very big then I will send part of it.
The function with problem is (inside pulse_cpp):
bool Sb_Actel::send_1000long_pulse(int node_id)
which I programed to send actually 100 pulses but it is ok...
I call this function from (case I D _ S C U R V E: ) from panel_of_function_cpp
If I run the procedure which is comented it works properly. If I run like it is now (calling another thread) it does not work well...
if you need something else tell me and I send more code...
Last edited by rafraf; February 21st, 2005 at 02:01 PM.
I am new in multithread (I am using it for the first time) and I really believe that the error is something simpler that it seems...
It could be that I am using a library that doesnt work well in a multithread process?? or I must use some libraries in order to get my program to work...??
I am using on Code Generation: Debug Multithread
and the function: CreateThread(...)
I have also tried with _beginthread( Func, 0, (void *) (ch++)); but the error persists...
any insight??
thanks...
Last edited by rafraf; February 22nd, 2005 at 09:18 AM.
When I get the routine inside the function I am calling (send_1000long_pulse) from the ThreadFunc and put it direct inside the ThreadFunc it works well...??
I will send a peace of this class to see if someone finds something wrong...
[QUOTE]
...
using namespace std;
class Sb_Actel
{
public:
Sb_Actel(); //constructor
~Sb_Actel(); //destructor
bool send_25ns_pulse(int node_id, int i2c_ch, BYTE DAC_value);
bool send_long_pulse(int node_id);
bool send_1000long_pulse(int node_id);
bool send_40M_clk(int node_id);
bool send_clk(int node_id, int i2c_ch, int counter_nr, int *value);
bool select_swpulse_mode(int node_id);
bool select_sw_start_stop_mode(int node_id);
bool set_tmis_time_ms(int node_id, int time);
bool write_ADDR_PULSE(int node_id);
private:
BYTE data[4];
int index_actel;
BYTE can_msg_cnf[4];
};
Rafraf, are you accessing the a resource (library, data, etc.) from more than one thread? If you are, then you need to guard the access of a resource with a synchronization object such as a critical section.
For example say I have a string resource that is accessed by two threads. If one thread is reading the string while the other thread is writing, there is going to be some data corruption (as the reading thread maybe getting some partially written data).
Could this be what is happening?
Btw, when you zip up your project, just zip the files up in their native format (*.h; *.cpp, etc.). That way, folks can load them up in the editor and get the benefit of getting color coded comments, formatting, etc. When saved as rtf files all this info is lost.
Yes, it could be...I am not using any protection but when I run this new thread I do not do nothing on the main thread, I just wait...(but pehaps it is not enough)
now I send some files of the program in the right way!
I will try to find out how to use synchronization object in my program, if you have any tutorial it would help.
Rafraf, for sychronization within a process, you probably don't need to use a mutex but can use a critical section instead. I've attached a simple dialog application that uses two threads to fill and populate a list control with about 100,000 items. Items are created on one thread and pushed on to an STL vector. The second thread reads the items from the vector. Both threads lock the vector using a critical section. See the LVItemDataMgr.h for specifics.
For ease of use, the critical section is contained in the following lightweight wrapper class:
To guard a resource, you can declare an instance of CLockableCS directly (CLockableCS m_csDataStruct or derive a class from CLockableCS such as the following std::vector derived class:
Code:
// Turn a std::vector into a lockable vector (this class stores an array of CLVItemData pointers)
class CLVItemDataList
: public std::vector< CLVItemData* >, public CLockableCS
{
public:
CLVItemDataList() {}
~CLVItemDataList() {}
};
Now to be really slick, we need a class that helps us perform the locking and automatic unlocking. Note: one the most common problems with regard to multithreaded programming is forgetting to release locks when they are no longer needed. IMO, a class such as this helps prevent these sorts of problems.
Next, let's put it all together with a class that uses a CLockableCS derived list and illustrates locking and unlocking:
Code:
class CLVItemDataMgr
{
public:
CLVItemDataMgr() : m_lMaxCount( 1000000 ) { }
~CLVItemDataMgr() { }
// Operations (public methods consumed by CLVSelStateDlg)
public:
// Cycle through the list and add each item into the list control
// NOTE: This code is called from Thread 1
HRESULT Populate( CListCtrl& ctlList )
{
HRESULT hr = S_OK;
// Lock the list
CAutoLockT< CLVItemDataList > lock( &m_LVItemDataList );
// Cycle through the list and add each item into the list control
for(CLVItemDataList::iterator it = m_LVItemDataList.begin();
it < m_LVItemDataList.end();
it++)
{
CLVItemData* pLVItemData = (*it);
// Add this item to the list control. NOTE: the actual code in the sample
// is different than below. This code has been modified for clarity
pLVItemData->AddToListControl( ctlList );
}
return hr;
}
// Implementation
private:
// Method: RetrieveThread (Thread 2)
// Purpose: Secondary Thread which adds Max Count items to the
// LVItem Data list
static UINT WINAPI RetrieveThread( LPVOID lpContext )
{
CLVItemDataMgr* pLVItemDataMgr
= static_cast< CLVItemDataMgr* >( lpContext );
for( LONG lIndex = 0;
lIndex < pLVItemDataMgr->GetMaxCount();
lIndex++ )
{
pLVItemDataMgr->InsertItem( lIndex );
}
return 0;
}
// Method: InsertItem
// Purpose: Creates a new CLVItemData object and inserts it into the list
HRESULT InsertItem( const UINT uIndex )
{
HRESULT hr = S_OK;
CString sColumnOne = _T(""),
sColumnTwo = _T("Col2"),
sColumnThree = _T("Col3");
sColumnOne.Format( _T("Col1 : %d"), uIndex );
CLVItemData* pLVItemData = new CLVItemData( sColumnOne,
sColumnTwo,
sColumnThree );
if( NULL == pLVItemData )
{
return E_OUTOFMEMORY;
}
try
{
// Lock the list. Prevent list access in thread 1
CAutoLockT< CLVItemDataList > lock( &m_LVItemDataList );
m_LVItemDataList.push_back( pLVItemData );
} // CAutoLockT goes out of scope and automatically unlocks here
catch(std::bad_alloc)
{
hr = E_OUTOFMEMORY;
}
return hr;
}
// Attributes
private:
// The lockable vector. This stl vector class holds pointers to
// CLVItemData objects.
CLVItemDataList m_LVItemDataList;
LONG m_lMaxCount;
};
This sample was originally created to illustrate a virtual listview, so there is quite a bit of UI stuff in there. However the main threading and locking code is contained within the CLVItemDataMgr.h file so it shouldn't be too hard to filter out the threading related code.
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.