must to use pthread library to compile multithreaded programs in MinGW environment?
I saw that the header file declared the _ beginthreadex function in the integrated MinGW, in TrueStudio. but there was an exception in the operation of the program. I don't know if I used the _ beginthreadex function.
//process.h
/* Thread initiation and termination functions.
*
* NOTE: Apparently _endthread() calls CloseHandle() on the handle of the
* thread, creating a potential for race conditions, if you are not careful.
* Basically, you MUST ensure that NOTHING attempts to do ANYTHING with the
* thread handle after the thread calls _endthread(), or returns from the
* thread function.
*
* NOTE: No old names for these functions. Use the underscore.
*/
_CRTIMP __cdecl __MINGW_NOTHROW
unsigned long _beginthread (void (*)(void *), unsigned, void *);
_CRTIMP __cdecl __MINGW_NOTHROW void _endthread (void);
#ifdef __MSVCRT__
_CRTIMP __cdecl __MINGW_NOTHROW unsigned long _beginthreadex
(void *, unsigned, unsigned (__stdcall *) (void *), void *, unsigned, unsigned *);
_CRTIMP __cdecl __MINGW_NOTHROW void _endthreadex (unsigned);
#endif
update:
Does the above information indicate that the _ beginthreadex function needs to be supported by the MSVC compiler, but not the _ beginthread function?
No don't have to use pthreads. You could use Win32 API directly.
hThreadArray[i] = CreateThread(
NULL, // default security attributes
0, // use default stack size
MyThreadFunction, // thread function name
pDataArray[i], // argument to thread function
0, // use default creation flags
&dwThreadIdArray[i]); // returns the thread identifier
And if you are concerned by portability, you could also go through libuv.
https://learn.microsoft.com/en-us/windows/win32/procthread/creating-threads
http://libuv.org/
Instead of MinGW you should use MinGW-w64, which is much more maintained and up to date and supports both Windows 32-bit and 64-bit.
As for threading, any MinGW(-w64) will provide the Windows threads API, but any MinGW-w64 build with POSIX threads support (like the standalone builds from https://winlibs.com/) will also allow you to use pthreads on Windows.
If for some reason you are stuck with classic MinGW you could also take a look at https://sourceforge.net/projects/pthreads4w/ to still be able to use pthreads.
Related
Or is it a function call? i know system calls are calls to a subroutine build in the system while function calls are calls within the program.
No system call is done when reading environment variables.
On the C API level, the environment variables are passed to main as the third argument. The complete prototype is:
int main(int argc, char *argv[], char *envp[])
If you define your main this way, you will not even need function call to read the environment.
The following program prints all of your environment variables:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[], char *envp[]) {
while( *envp ) {
printf("%s\n", *envp);
envp++;
}
return 0;
}
Of course, main is just something invented by your compiler's runtime support libraries. As far as the OS is concerned, the interface is somewhat different. The same principle still stands, however. The environment is passed to the newly created program after execve on its stack.
This is also why getenv returns a char *. It does not need to allocate anything. It already has the string.
Edited to add: It is quite simple to know whether any specific function results in a system call or not (and which). All you have to do is run strace over the code. strace traps all (and only) system calls. If your getenv function call is invisible to it, it is not a system call.
I have a native c++ library that gets used by a managed C++ application. The native library is compiled with no CLR support and the managed C++ application with it (/CLR compiler option).
When I use a std::mutex in the native library I get a heap corruption when the owning native class is deleted. The use of mutex.h is blocked by managed C++ so I'm guessing that could be part of the reason.
The minimal native class that demonstrates the issue is:
Header:
#pragma once
#include <stdio.h>
#ifndef __cplusplus_cli
#include <mutex>
#endif
namespace MyNamespace {
class SomeNativeLibrary
{
public:
SomeNativeLibrary();
~SomeNativeLibrary();
void DoSomething();
#ifndef __cplusplus_cli
std::mutex aMutex;
#endif
};
}
Implementation:
#include "SomeNativeLibrary.h"
namespace MyNamespace {
SomeNativeLibrary::SomeNativeLibrary()
{}
SomeNativeLibrary::~SomeNativeLibrary()
{}
void SomeNativeLibrary::DoSomething(){
printf("I did something.\n");
}
}
Managed C++ Console Application:
int main(array<System::String ^> ^args)
{
Console::WriteLine(L"Unit Test Console:");
MyNamespace::SomeNativeLibrary *someNativelib = new MyNamespace::SomeNativeLibrary();
someNativelib->DoSomething();
delete someNativelib;
getchar();
return 0;
}
The heap corruption debug error occurs when the attempt is made to delete the someNativeLib pointer.
Is there anything I can do to use a std::mutex safely in the native library or is there an alternative I could use? In my live code the mutex is used for is to ensure that only a single thread accesses a std::vector.
The solution was to use a CRITICAL_SECTION as the lock instead. It's actually more efficient than a mutex in my case anyway since the lock is only for threads in the same process.
Not sure were you reading your own post but there is a clue in your code:
#ifndef __cplusplus_cli
std::mutex aMutex;
#endif
Member 'aMutex' compiles only if compile condition '__cplusplus_cli' is undefined.
So the moment you included that header in Managed C++ it vanished from definition.
So your Native project and Managed project have mismatch in class definition for beginners == mostly ends in Access Violation if attempted to write to location beyond class memory (non existing member in CLI version if instantiated there).
Or just HEAP CORRUPTION in managed code to put it simply.
So what you have done is no go, ever!
But I was actually amazed that you managed to include native lib, and successfully compile both projects. I must ask how did you hack project properties to manage that. Or you just may have found yet another bug ;)
About question: for posterity
Yes CRITICAL_SECTION helps, Yes it's more faster from mutex since it is implemented in single process and some versions of it even in hardware (!). Also had plenty of changes since it's introduction and some nasty DEAD-LOCKS issues.
example: https://microsoft.public.win32.programmer.kernel.narkive.com/xS8sFPCG/criticalsection-deadlock-with-owningthread-of-zero
end up just killing entire OS. So lock only very small piece of code that actually only accesses the data, and exit locks immediately.
As replacement, you could just use plain "C" kernel mutex or events if not planning cross-platform support (Linux/iOS/Android/Win/MCU/...).
There is a ton of other replacements coming from Windows kernel.
// mutex
https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createmutexw
HANDLE hMutex = CreateMutex(NULL, TRUE, _T("MutexName"));
NOTE: mutex name rules 'Global' vs 'Local'.
// or event
https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createeventw
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, _T("EventName"));
to either set, or clear/reset event state, just call SetEvent(hEvent), or ResetEvent(hEvent).
To wait for signal (set) again simply
int nret = WaitForSingleObject(hEvent, -1);
INFINITE define (-1) wait for infinity, a value which can be replaced with actual milliseconds timeout, and then return value could be evaluated against S_OK. If not S_OK it's most likely TIMEOUT.
There is a sea of synchronization functions/techniques depending on which you actually need to do !?:
https://learn.microsoft.com/en-us/windows/win32/sync/synchronization-functions
But use it with sanity check.
Since you might be just trying to fix wrong thing in the end, each solution depends on the actual problem. And the moment you think it's too complex know it's wrong solution, simplest solutions were always best, but always verify and validate.
What is the difference between C++11 functions get_id() and native_handle()?
In the test program I created they return the same int value for their threads so I have no idea what the difference is.
I'm using GCC 4.8.1 on Windows.
From this reference:
get_id returns the id of the thread
and
native_handle returns the underlying implementation-defined thread handle
The thread identifier as returned by get_id should actually be a class (std::thread::id) and not a number or other platform specific handle.
The native_handle function returns just what its name implies, a native handle that can be used by the underlying operating systems thread functions. On Windows this is typically a HANDLE as returned by CreateThread, on POSIX platforms it's typically a pthread_t as initialized by pthread_create.
I have created wrappers around the pthread functions using dlopen and dlsym, in order to debug and profile some issues occurring in my application. The profiler passes all of the unit tests. Unfortunately, it appears that I have bypassed some library initialization because getenv now returns null to all input. If I remove the profiler, the proper operation of getenv returns.
I believe that the issue is that the compiler has not linked in Libpthread because it does not see any symbols requested from the library at link time. I have looked through the glib source but have not found an obvious run time initialization function that I can load and execute with dlsym.
I have stepped into getenv and found that __environ=null with the overrides compiled in. However, environ contains the proper values. __environ has the proper variables after removing the profiler.
Also, getenv appears to work with the pthread overrides on Ubuntu 10.04, with glibc 2.11. Unfortunately, upgrading is not an appealing option due to existing product distribution.
Linux 2.6.31
Glib 2.5
My init code:
inline int init_pthreads_debugger(void)
{
static int recursion=0;
if(!real_pthread_create)
{
// we know that we are single threaded here, because we override pthread_create and
// call this function. Therefore, recursion does not have to be guarded.
if(recursion)
{
return 0;
}
recursion = 1;
init_heap();
void * handle = dlopen("libpthread.so.0",RTLD_NOW);
real_pthread_cond_timedwait =(real_pthread_cond_timedwait_t)dlsym(handle,"pthread_cond_timedwait");
// more pthread initialization functions here.
//do me last to make sure any recursion in dlsym/dlopen is caught
real_pthread_create =(real_pthread_create_t)dlsym(handle,"pthread_create");
recursion = 0;
}
return 1;
}
//an example override
int pthread_cond_timedwait(pthread_cond_t *c, pthread_mutex_t * m, const struct timespec * t)
{
if(!init_pthreads_debugger()) return 0; //no thread, no sync needed.
int ret;
int condition_count;
ptd_note_unblock((void *)m,&condition_count);
ret=real_pthread_cond_timedwait(c,m,t);
ptd_note_block((void *)m,&condition_count);
return ret;
}
thanks for any help.
I have created wrappers around the pthread functions using dlopen and dlsym
I suspect that you are attempting to build a library interposer, similar to this one.
This approach is very unlikely to succeed in general for pthread functions, because both dlopen and dlsym themselves call pthread_mutex_lock and pthread_mutex_unlock (and possibly others), as does the dynamic loader itself.
Are there languages that support process common memory in one address space and thread specific memory in another address space using language features rather than through a mechanism like function calls?
process int x;
thread int y;
ThreadStatic attribute in C#
The Visual C++ compiler allows the latter through the nonstandard __declspec(thread) extension - however, it is severly limited, since it isn't supported in dynamically loaded DLLs.
The first is mostly supported through an extern declaration - unless dynamically linked libraries come into play (which is probably the scenario you are looking for).
I am not aware of any environment that makes this as simple as you describe.
C++0x adds the "thread_local" storage specifier, so in namespace (or global) scope your example would be
int x; // normal process-wide global variable
thread_local int y; // per-thread global variable
You can also use thread_local with static when declaring class members or local variables in a function:
class Foo {
static thread_local int x;
};
void f() {
static thread_local int x;
}
Unfortunately, this doesn't appear to be one of the C++0x features supported by Visual Studio 2010 or planned GCC releases.