|
mikeorama12345 wrote: Just imagine if we could disable switching momentarily so that we could execute a couple of lines of code and guarantee that no other threads were run in between.
Isn't this what a critical section does?
"The largest fire starts but with the smallest spark." - David Crow
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
All a critical section does is prevent another thread from running the protected section of code. He was asking about totally preventing other threads from running, which isn't possible.
--Mike--
Visual C++ MVP
LINKS~! Ericahist | PimpFish | CP SearchBar v3.0 | C++ Forum FAQ
VB > soccer
|
|
|
|
|
It is, but I think you have to be running Windows 3.1
|
|
|
|
|
Michael Dunn wrote: He was asking about totally preventing other threads from running,
I don't think so, but I'd like to hear what the originator says.
Michael Dunn wrote: which isn't possible.
Why not?
Best,
Jun
|
|
|
|
|
Jun Du wrote: I don't think so, but I'd like to hear what the originator says.
Isn't this the only way both threads can remain time synchronized? I mean the only way I can see this to work is he has to have a dual processor dual core machine with the two threds on their own cpu and that the operating system will never schedule any other threads (or yield execution) on either of the cpus that are runing the two threads.
|
|
|
|
|
My reply "I don't think so" is to Michael's comment that the originator wanted to prevent other threads from running. I think what the originator wanted (or needed) is sychronizing the tweo threads so that they output the same frame at a given time.
I see two issues mixed with the originator's question: real-time and synchronization. By real-time, I mean that the simulation time your program complete goes hand-in-hand with your wall clock, no faster no slower. Lets say you're simulating the traffic on a highway. You want your program to complete the simulation of one sencond traffic within one second time. Only this way you can acheive real-time. Multiple CPUs can help to acheive real-time through better parallelism. But if the computation is very simple, one CPU can do the job too. As you may notice now, parallelism is not a necessity in pursuing real-time.
Synchroniztion is a different issue. It is about the collaboration between two threads. It has nothing to do with how fast your CPU is. You don't need multiple CPUs to acheive synchronization. One of the major purposes for synchronization is protecting resources shared by more than one thread.
Best,
Jun
|
|
|
|
|
mikeorama12345 wrote: mswin does not provide us with much control of threads.
Compared to what, Linux?
|
|
|
|
|
That is what Mutex's, Semaphores/Critical Sections are for.
Almost forgot ... and events.
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
-- modified at 15:31 Tuesday 27th June, 2006
|
|
|
|
|
mutex, boraphores, and critical sectionz are a bunch of clutter and a lot of work.
This is America. I dont want to work so hard.. I want to live!
I hope some day they invent simple macros:
LockThread ()
blah blah blah // YEY! I have 100% CPU unless timeout
UnLockThread ()
blah blah blah // ok go ahead and switch threads on me now, i dont care
Thread switching probably requires interrupts.
maybe we can use asm sti and cli ? (set interrupt and clr interrupt)
Just livin a dream.. dont wake me!
|
|
|
|
|
You mean something like this:
Main Thread
<br />
struct myData<br />
{<br />
shared_ptr<CCriticalSection> ptr;<br />
};<br />
<br />
void main()<br />
{<br />
shared_ptr<CCriticalSection> mySection(new CCriticalSection);<br />
myData data;<br />
data.ptr = mySection;<br />
HANDLE hThreads[2];<br />
hThreads[0] = CreateThread(..., &data);
hThreads[1] = CreateThread(..., &data);
<br />
while (WaitForMultipleObjects(...) == WAIT_TIMEOUT)<br />
{<br />
}<br />
}<br />
Threads 1 and 2
int Thread1(LPARAM pParam)<br />
{<br />
myData data = *(myData*)pParam;<br />
shared_ptr<CCriticalSection> mySection = data.ptr;<br />
<br />
while (IDoSomething())<br />
{<br />
mySection->Lock();<br />
mySection->Unlock();<br />
}<br />
return 0;<br />
}
Yes, sooo much more clutter ...
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
This was how it used to work with windows3.1 but a bad side affect of this is that with this policy any application could steal 100% of the cpu for as long as it wants and if it crashed during this time down went the os.
|
|
|
|
|
depends cpu count
waitt0
t0
++
signalglobal
waitt1
t1
++
signalglobal
waitglobal
if ()
signal t0,t1
Kuphryn
|
|
|
|
|
Windows is not a real-time OS, it does not give you control over when your threads will run. You can try increasing the threads' priority, but still, if some higher-priority task comes along, it will get CPU time and there's nothing you can do about it.
--Mike--
Visual C++ MVP
LINKS~! Ericahist | PimpFish | CP SearchBar v3.0 | C++ Forum FAQ
VB > soccer
|
|
|
|
|
Thanks for all your replies. Yep, I think my question should state as 'Parallel/simultaneous processing of multiple threads'. Synchronization is more related to resource sharing between threads. The problem is to run both threads exactly at same speed and at the same time (which assures the frame rate). I have tried several ways by defining the priority classes to both threads to HIGH_PRIORITY_CLASS and setting their priority to PRORITY_TIME_CRITICAL, but still 'sometimes' I am getting a difference of one frame between 2 threads. I am running my application on a Dell Precision 670 (Dual xeon processors) with 2 threads on each core.
Here is how my application works-
I am having 2 waveform generating boards on 2 of my 64-bit PCI slots. In my application I am generating waveforms on both of these boards and each thread generates waveforms on each of these boards. These boards will have on-board buffers where we can store the data to be generated as waveforms. Since these buffers are to be in multiples of 1024 and my data is not in multiples of 1024, as usual, I am using rotating buffers. The board buffers, data buffers are completely independent for both threads (each thread is having its own buffers), so no data is shared between these threads except the intial flag variable which initiates the starting loop in the thread. Neither of these threads change the flag. They just use it to start their wave form generating loop (just like as a trigger signal).
At last I would like to know how we can make sure these threads run at the same rate and speed and at any given instant of time they both should be at the same point of execution (one more thing is both these threads have exact and same number of instructions).
thanks,
-Pavan
|
|
|
|
|
hello
when I write :
mouse_event(MOUSEEVENTF_RIGHTUP
,mouse.x
,mouse.y
,0
,GetMessageExtraInfo());
it works , but with MOUSEEVENTF_LEFTUP notting happens.
do anyone knows anyway?
thanks
|
|
|
|
|
how to access com port in VC++
|
|
|
|
|
Using CreateFile() is one way.
"The largest fire starts but with the smallest spark." - David Crow
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
#ifndef _COMPORT_H
#define _COMPORT_H
#include <afxwin.h>
//////////////////////////////////////////////////////////////////////
class Comport
{
private:
HANDLE hdev;
int slen;
int rxp;
char sbuf [1024];
public:
int Com, Baud;
Comport ();
~ Comport ();
int Open ( int com, int baud );
void Close ();
void SetBaud ( int baud );
void CommState ();
void CommTO ();
int read ( char * s, int size );
int write ( char * s, int size );
int putc ( char c );
int puts ( char * s );
int getc ();
int Read ();
int SendFile ( const char * );
};
//////////////////////////////////////////////////////////////////////
#endif
#include "timer.h"
#include "comport.h"
#include <stdio.h>
/**************************************************************/
Comport :: Comport ()
{
hdev = 0;
Com =
Baud = 0;
}
/**************************************************************/
Comport :: ~ Comport ()
{
Close ();
}
/**************************************************************/
void Comport :: Close ()
{
if ( hdev && CloseHandle ( hdev ) == FALSE )
{
}
hdev = 0;
Com =
Baud = 0;
}
/**************************************************************/
Comport :: Open ( int com, int baud )
{
if ( Com && hdev ) Close ();
if (!( Com = com )) return 0;
Baud = baud;
char s [255];
sprintf ( s, "\\\\.\\COM%d", Com );
hdev = CreateFile ( s, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0 );
int error = GetLastError();
// hdev = (void*)HFILE_ERROR;
if ( (int) hdev != HFILE_ERROR )
{
CommState ();
CommTO ();
}
else Com = 0;
return Com;
}
/**************************************************************/
void Comport :: SetBaud ( int baud )
{
if ( Com )
{
Baud = baud;
CommState ();
}
}
/**************************************************************/
void Comport :: CommState ()
{
DCB dcb;
GetCommState ( hdev, & dcb );
dcb .BaudRate = Baud;
dcb .ByteSize = 8;
dcb .StopBits = ONESTOPBIT;
dcb .Parity = NOPARITY;
dcb .fBinary = 0;
dcb .fParity = 0;
dcb .fOutxCtsFlow = 0;
dcb .fOutxDsrFlow = 0;
dcb .fDtrControl = DTR_CONTROL_DISABLE;
dcb .fDsrSensitivity = 0;
// dcb .fTXContinueOnXoff =
dcb .fOutX = 0;
dcb .fInX = 0;
dcb .fErrorChar = 0;
dcb .fNull = 0;
dcb .fRtsControl = RTS_CONTROL_DISABLE;
dcb .fAbortOnError = 0;
SetCommState ( hdev, & dcb );
}
/**************************************************************/
void Comport :: CommTO ()
{
COMMTIMEOUTS cto;
cto .ReadIntervalTimeout = MAXDWORD;
cto .ReadTotalTimeoutMultiplier = 0;
cto .ReadTotalTimeoutConstant = 0;
cto .WriteTotalTimeoutMultiplier = 0;
cto .WriteTotalTimeoutConstant = 0;
SetCommTimeouts ( hdev, & cto );
}
/**************************************************************/
int Comport :: read ( char * b, int size )
{
DWORD n = 0; //bytesRead
ReadFile ( hdev, b, size, & n, 0 );
return n;
}
/**************************************************************/
int Comport :: write ( char * b, int size )
{
DWORD n = 0; //bytesWritten
WriteFile ( hdev, b, size, & n, 0 );
return n;
}
/**************************************************************/
int Comport :: putc ( char c )
{
return write ( & c, 1 );
}
/**************************************************************/
int Comport :: puts ( char * s )
{
return write ( s, strlen (s) );
}
/**************************************************************/
int Comport :: SendFile ( const char * path )
{
int n = 0;
if (Com)
if ( FILE * fp = fopen ( path, "rt" ) )
{
Ticker t(50);
char s [100] = {0};
while ( fgets ( s, 100, fp ) )
{
while (!t .expire () );
n += write ( s, strlen (s) );
}
}
return n;
}
/**************************************************************/
int Comport :: Read ()
{
rxp = 0;
DWORD size = 0;
if (Com)
ReadFile ( hdev, sbuf, 1024, & size, 0 );
return slen = size;
}
/**************************************************************/
int Comport :: getc ()
{
coerce ( 0, 1023, rxp );
coerce ( 0, 1023, slen );
return ( rxp < slen ) ? sbuf [ rxp ++ ] : 0 ;
}
/**************************************************************/
/*int Comport :: getc ()
{
char inbuf [25] = {0};
read ( inbuf, 1 );
return inbuf [0];
}
/**************************************************************/
Just livin a dream.. dont wake me!
|
|
|
|
|
See Here[^] maybe it is some helpful to you
whitesky
|
|
|
|
|
I have all strings in a mySQL table and then use a Perl script to create .rc files for the different languages.
I can than add one of those .rc files to my resource includes for a particular language.
My problem now is that I want a single exe without satellite DLLs for the different languages. That doesn't seem to be possible, because each string id can only be in one string table and it is also not possible to select a particular string table.
My idea now was to add XML files with the strings to my resources and to overload LoadString. But I'm not sure if that also works with unicows on Win9x?
Are there any other options to support multiple languages from a single exe?
Thanks André
|
|
|
|
|
One possibility is to use ranges. Thus, all English strings could zero based, all of language 2 could start at 10,000; language 3, 20,000 and so forth. This is limiting, but can be done.
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
Joe Woodbury wrote: One possibility is to use ranges.
Unfortunately that doesn't work, at least not without a custom LoadString function. LoadString looks in the table for an id (number) and then copies the string from the table to the buffer. Therefore it would always load the string of the language without an offset.
|
|
|
|
|
ABuenger wrote: at least not without a custom LoadString function.
That goes without saying.
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
Joe Woodbury wrote: That goes without saying.
extern "C"<br />
{<br />
int WINAPI LoadStringW (HINSTANCE hInstance, UINT uID, LPWSTR lpBuffer, int nBufferMax)<br />
{<br />
return 0;<br />
}<br />
};
Results in a warning C4273: 'LoadStringW' : inconsistent dll linkage. dllexport assumed.
And my own function never gets called
|
|
|
|
|
I wouldn't overload LoadString directly. Rather I'd add a function like MyLoadString which would have smarts about what the current language is and all that. The advantage of this is that it could account for language neutral strings and whether satellite DLLs are used or not--in other words, the rest of your code wouldn't care where the strings are or how they are organized. For CString, you could have an overloaded version of MyLoadString that took a reference to a CString object and the ID (or you could always return a CString--there are many possibilities.)
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|