Source Code of Pthread Library

Source code of PThread Library?

You can find the source at both of these links:

http://www.opengroup.org/onlinepubs/009695399/basedefs/pthread.h.html

http://code.google.com/p/pthread-lib/source/browse/trunk/pthread-lib/src/ptl_array_list.c

Code of the function pthread_join - Pthread Library

There is not "the code", there are many different implementations that partially build on each other. For example

  • The GNU C Library if you are using gcc
  • Google's implementation for Android
  • Apple's implementation

Install third party POSIX Threads for Windows

Here is how I put things together. The goal is to have pthread available as system library on Microsoft Windows so I can just #include <pthread.h> to my source code to use its functions.

The main issue is that the compiler/linker can find all parts of the library which are the header file pthread.h, the linkable library pthread.lib and its executable part pthread.dll. It will look at predefined directories. For the header file it will look at the environment variable INCLUDE or will use settings in environment variable CL. INCLUDE is only used by the buildsystem nmake. Builds with Visual Studio does ignore it. Settings in CL is used by the compiler so it works on both buildsystems and we will use that. For pthread.lib the compiler looks at the environment variable LIB and the executable program searches for the needed pthread.dll using the Path environment variable.

I use the PowerShell. First we have to download and install pthreads4w from GitHub. It uses cmake and can only be compiled with nmake so we have to use the Generator 'NMake Makefiles'.

PS> git clone https://github.com/jwinarske/pthreads4w.git
PS> cd pthreads4w
PS> cmake -S . -B build -G 'NMake Makefiles' -D BUILD_TESTING=OFF -D CMAKE_BUILD_TYPE=Debug
PS> cmake --build build --config Debug --target install
--- snip ---
Install the project...
-- Install configuration: "Debug"
-- Installing: C:/Users/ingo/devel/pthreads4w/PTHREADS-BUILT/x86_64/Debug/bin/pthreadVCE3d.dll
-- Installing: C:/Users/ingo/devel/pthreads4w/PTHREADS-BUILT/x86_64/Debug/lib/pthreadVCE3d.lib
-- Installing: C:/Users/ingo/devel/pthreads4w/PTHREADS-BUILT/x86_64/Debug/bin/pthreadVSE3d.dll
-- Installing: C:/Users/ingo/devel/pthreads4w/PTHREADS-BUILT/x86_64/Debug/lib/pthreadVSE3d.lib
-- Installing: C:/Users/ingo/devel/pthreads4w/PTHREADS-BUILT/x86_64/Debug/bin/pthreadVC3d.dll
-- Installing: C:/Users/ingo/devel/pthreads4w/PTHREADS-BUILT/x86_64/Debug/lib/pthreadVC3d.lib
-- Installing: C:/Users/ingo/devel/pthreads4w/PTHREADS-BUILT/x86_64/Debug/lib/libpthreadVCE3d.lib
-- Installing: C:/Users/ingo/devel/pthreads4w/PTHREADS-BUILT/x86_64/Debug/lib/libpthreadVSE3d.lib
-- Installing: C:/Users/ingo/devel/pthreads4w/PTHREADS-BUILT/x86_64/Debug/lib/libpthreadVC3d.lib
-- Installing: C:/Users/ingo/devel/pthreads4w/PTHREADS-BUILT/x86_64/Debug/include/_ptw32.h
-- Installing: C:/Users/ingo/devel/pthreads4w/PTHREADS-BUILT/x86_64/Debug/include/pthread.h
-- Installing: C:/Users/ingo/devel/pthreads4w/PTHREADS-BUILT/x86_64/Debug/include/sched.h
-- Installing: C:/Users/ingo/devel/pthreads4w/PTHREADS-BUILT/x86_64/Debug/include/semaphore.h

That's where you find all headers, libs and dlls. Or something clearer:

.\PTHREADS-BUILT\
└── x86_64
└── Debug
├── bin
│   ├── pthreadVC3d.dll
│   ├── pthreadVCE3d.dll
│   └── pthreadVSE3d.dll
├── include
│   ├── _ptw32.h
│   ├── pthread.h
│   ├── sched.h
│   └── semaphore.h
└── lib
├── libpthreadVC3d.lib
├── libpthreadVCE3d.lib
├── libpthreadVSE3d.lib
├── pthreadVC3d.lib
├── pthreadVCE3d.lib
└── pthreadVSE3d.lib

There are some more libraries using exeptions but we only use the default and recommended shared version pthreadVC3d. For details about this naming look at the README of the project.

Now we provide the generic library name pthread.lib with a symlink and set the environment variables.

PS> cd PTHREADS-BUILT\x86_64\Debug\lib\
PS> new-item -itemtype symboliclink -path . -name pthread.lib -value pthreadVC3d.lib
PS> $env:CL = "/I C:\Users\ingo\devel\pthreads4w\PTHREADS-BUILT\x86_64\Debug\include"
PS> $env:LIB += ";C:\Users\ingo\devel\pthreads4w\PTHREADS-BUILT\x86_64\Debug\lib"
PS> $env:Path += ";C:\Users\ingo\devel\pthreads4w\PTHREADS-BUILT\x86_64\Debug\bin"

Don't forget the plus sign and the starting semi colon. For testing it I use this simple program:

PS> type .\simple_pthread.cpp

#include <pthread.h>

#include <iostream>

namespace // no name, i.e. anonymous for file scope
// this is the C++ way for decorator STATIC
{
void* start_routine(void*) {
std::cout << "-- Hello from POSIX Thread" << std::endl;
return 0; // calls pthread_exit()
}
} // namespace

int main() {
pthread_t thread;
int rc;
void* retval;

std::cout << "-- starting POSIX Thread" << std::endl;

rc = pthread_create(&thread, NULL, &start_routine, NULL);
if (rc != 0) {
std::cerr << "Error! unable to create thread, rc=" << rc << std::endl;
exit(1);
}

rc = pthread_join(thread, &retval);
if (rc != 0) {
std::cerr << "Error! Unable to join thread with rc=" << rc << std::endl;
exit(1);
}
if (retval != NULL) {
std::cerr << "Error! Thread failed with retval=" << retval << std::endl;
exit(1);
}

return 0;
}

Now use it (where ever you have it stored):

PS> cl /EHsc .\simple_pthread.cpp pthread.lib
PS> .\simple_pthread.exe
-- starting POSIX Thread
-- Hello from POSIX Thread

how to remove pthread undefined reference while building single thread library

If you are certain no actual pthread code gets called from the code path your library uses then you could try making dummy versions of the ptherad calls like this:

DummyPThreads.c (note c not c++)

int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void *), void*)
{
return 0;
}

void pthread_exit(void*)
{
}

// etc...

Compile with:

gcc -c -o DummyPThreads.o DummyPThreads.c

Add to your application:

g++ -o noThread MAIN.cpp -I../A -I../B DummyPThreads.o -L../A -L../B -lB -lA

Why does GCC's threading standard library implementation throw exceptions if you don't include pthread?

The reason for this is that libstdc++ uses the so called weak references.

We can easily trace why your particular code example throws an exception. set_value() calls std::call_once. That function in its implementation has the line*:

int e = gthread_once(&once.M_once, &once_proxy);

where gthread_once is:

static inline int gthread_once(gthread_once_t *once, void (*func)(void))
{
if (gthread_active_p())
return ...
else
return -1;
}

gthread_active_p returns false, that's why gthread_once returns -1, which is mentioned in the exception string.

Now let's take a look at gthread_active_p:

static __typeof(pthread_key_create) gthrw_pthread_key_create
__attribute__ ((weakref("__pthread_key_create")));

static inline int gthread_active_p(void)
{
static void *const gthread_active_ptr = (void *)>hrw_pthread_key_create;
return gthread_active_ptr != 0;
}

gthrw_pthread_key_create is a weak reference to __pthread_key_create. If there is no symbol __pthread_key_create found by the linker, >hrw_pthread_key_create will be a null pointer, if __pthread_key_create is found, gthrw_pthread_key_create will be an alias for it. __pthread_key_create is exported by the pthreads library.

The standard library source code also contains the following comment:

For a program to be multi-threaded the only thing that it certainly must be using is pthread_create. However, there may be other libraries that intercept pthread_create with their own definitions to wrap pthreads functionality for some purpose. In those cases, pthread_create being defined might not necessarily mean that libpthread is actually linked in.

For the GNU C library, we can use a known internal name. This is always available in the ABI, but no other library would define it. That is ideal, since any public pthread function might be intercepted just as pthread_create might be. __pthread_key_create is an "internal" implementation symbol, but it is part of the public exported ABI. Also, it's among the symbols that the static libpthread.a always links in whenever pthread_create is used, so there is no danger of a false negative result in any statically-linked, multi-threaded program.


* Some underscores are removed and macros are expanded to improve readability.

pthread static linking with application in visual studio 2013

In my case i was not having static lib and i was trying to do static link with dynamic lib. Following are steps to do static linking .

  1. Download source code of Pthread_Win32 and build it with visual studio.
  2. So now you will have static lib (pthread_lib.lib) probably at path .........\pthread-win32-master\pthread-win32-master\bin\Win32_MSVC2013.Release
  3. In your application go into project properties mainly
    Linker->input->additional dependency and add pthread_lib.lib.
  4. Also add path of pthread_lib.lib into visual studio properties Linker->General->Additional Library Directories.
  5. Add this code #define PTW32_STATIC_LIB in header file.


Related Topics



Leave a reply



Submit