|
|
If say a process creates a semaphore/mutex etc then will this semaphore get created in its address space?
If yes then how an another process which wants to acquire this semaphore(created by the first process) will access the first process address space to acquire the semaphore?
Anybody can pls explain me this?
|
|
|
|
|
Semaphores, Mutexes etc. are kernel objects and memory is allocated in the kernel address space.
The processes that access these kernel objects which open handles to the objects.
The kernel object will be deallocated when the last handle referencing the object is closed.
|
|
|
|
|
superman does this reply my question?
|
|
|
|
|
Each process has its own handle table.
When you create a new mutex, memory is allocated elsewhere, but a handle is held within each process that references this mutex.
|
|
|
|
|
Thanks Superman for the inputs.
Ok so this means that the mutex/semaphore will not be allocated in the process address space but in some other shared address space where it will be shared by multiple process/threads. Am I correct?
So when an another thread/process tries to access a shared resource then it will see that the particular resource is protected by a certain mutex/semaphore and then it will try to get the handle to the mutex/semaphore using some mechanism. Is my thinking ok?
|
|
|
|
|
Process/Thread synchronization has to be handled by the programmer.
What I mean is that, for any shared resource intended to be protected by a mutex or semaphore, the wait functions[^] must be used on the handles of these objects so that these resources remain synchronized.
The wait functions will block access till a mutex or semaphore is release using ReleaseMutex or ReleaseSemaphore respectively.
|
|
|
|
|
Hi,
LoadAccelerators function is returning NULL value. im using the following code:
HACCEL m_hAccelTable1;
m_hAccelTable1 = LoadAccelerators(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCELERATOR2));
GetLastError function is returning 1814 error value which states that "The specified resource name cannot be found in the image file". The accelerator table is present in the resource file. Anyone please tell me where i did the mistake?
Thanks,
|
|
|
|
|
Check if IDR_ACCELERATOR2 is the right value to pass.
You could even check if that is the right value by opening the .RC file in text mode.
|
|
|
|
|
It is there in the resource file:
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
IDR_ACCELERATOR2 ACCELERATORS DISCARDABLE
BEGIN
"V", IDC_BMP_VIEW, VIRTKEY, NOINVERT
END
|
|
|
|
|
Is the accelerator table resource part of the EXE project or any other DLL that the EXE loads?
|
|
|
|
|
it is in a dll,but i have added the accelerator table in dll only. Another exe loads it.
|
|
|
|
|
In that case the error is in using the AfxGetInstanceHandle function.
Instead use GetModuleHandle with the name of the DLL as parameter.
|
|
|
|
|
|
Is it posible to create accelerator keys in a dll?
|
|
|
|
|
Yeah, accelerator tables can be stored in executables (PE files) as resources (if that's what you're asking). In fact it where they're normally stored. They're loaded with the LoadAccelerators[^] function.
Steve
|
|
|
|
|
Check the HINSTANCE handle is referring to the correct DLL.
Steve
|
|
|
|
|
|
I am currently using the Visual Studio 2010 Release Candidate and have ordered a full version ... but ... my order seems to be stuck "On Order". The expected dispatch date is today but I am not holding my breath. I have eight days left on the RC and I am beginning to get a little nervous.
Does anyone know if I can upgrade from the RC to the trial version to cover the gap? Any experiences or pointers worth sharing?
Paul Hooper
If you spend your whole life looking over your shoulder, they will get you from the front instead.
|
|
|
|
|
Code:
class MyClass
{
public:
MyClass(int iType);
};
class YourClass
{
public:
YourClass();
MyClass mys[2];
};
How to init constructor of MyClass for array mys[2] at:
YourClass::YourClass()
{
}
Impossible?
modified on Sunday, June 20, 2010 7:44 PM
|
|
|
|
|
You can create an Init method and call it for each element in the array.
|
|
|
|
|
Good question. I can't believe I've never ran into this before. I don't see any clean way around it.
Steve
|
|
|
|
|
I've come across this a couple of times before and I didn't find any other method than to assign values separately to each object in the array.
|
|
|
|
|
Unfortunately, the language don't specify any construct to pass parameters to the array constructing elements.
std::vector does this, essentially with a trick (to allow array grow and shrink it doesn't allocate "array" but "bulk buffers".
You can emulate this trick yourself this way:
class Element
{
public:
Element(ParamType _a)
{ ... }
private:
};
static const size_t BUFSZ = ...;
class Aggregate
{
public:
Aggregate(ParamType _a) :vector()
{
vector = reinterpret_cast<Element*>(buffer);
for(size_t i=0; i<BUFSZ; ++i)
new(vector+i)Element(_a);
}
Aggregate(const Aggregate& _s)
{
vector = reinterpret_cast<Element*>(buffer);
for(size_t i=0; i<BUFSZ; ++i)
new(vector+i)Element(_s.vector[i]);
}
~Aggregate()
{
for(size_t i=0; i<BUFSZ; ++i)
vector[i].~Element();
}
private:
char buffer[BUFSZ*sizeof(Element)];
Element* vector;
};
The advantage respect to std::vector is that memory is not allocated dynamically, but - Being BUFZ statically note, it can stay into the aggregate space.
The "other way" is to let Element s to default-construct someway, and than assign them the required values.
It mostly depend on the fact you can -or not- accept a default initialization for Element-s putting them in a sort of invalid state until they are assigned.
2 bugs found.
> recompile ...
65534 bugs found.
|
|
|
|
|
If you don't have to use an array (and generally there's no point), can use a vector and want each element initialised to the same value:
class YourClass
{
public:
YourClass() : mys( 2, MyClass( 7 ) )
{}
std::vector<MyClass> mys;
};
will do the trick. If you want different values then it's a bit trickier unless they're known at compile time. I won't bother going over that here though, please post if you want to know how to do it.
If you want them to all have different values and have an array set at compile time you're going to have to manage the construction and destruction yourself into a raw memory buffer:
class B
{
public:
B( int ) {}
};
class A
{
public:
A() : values_( reinterpret_cast<B (&)[2]>( raw_buff_[ 0 ] ) )
{
}
private:
char raw_buff_[ sizeof( B[2] ) ];
B (&values_)[2];
};
How you write the body of the constructor for A then depends on whether you want one value or different values. If you want the same value you can use initialized_fill:
A() : values_( reinterpret_cast<B (&)[2]>( raw_buff_[ 0 ] ) )
{
std::uninitialized_fill( &values_[ 0 ], &values_[ 2 ], B( 7 ) );
}
If you want to have different values you'll have to use something like construct (if your standard library supports it, it was in the SGI STL but not in the standard) or write your own:
template <class T1, class T2> void construct(T1* p, const T2& value)
{
new( p ) T1( value );
}
and then use it to implement your constructor:
A() : values_( reinterpret_cast<B (&)[2]>( raw_buff_[ 0 ] ) )
{
construct( &values_[ 0 ], B( 1 ) );
construct( &values_[ 1 ], B( 2 ) );
}
In either case you're going to want a destructor as you have to manually run the destructor for the elements in the array:
template <class T> void destroy(T* p)
{
p->~T();
}
~A()
{
destory( &values_[ 0 ] );
destroy( &values_[ 1 ] );
} Generally don't use C-style arrays unless you really have to. There's usually a solution in the standard library that's (almost) as good and far less fiddly to use.
Cheers,
Ash
Edited: Forgot the destructor.
|
|
|
|