Friday, June 12, 2015

Pthread Programming in VS2010

For Pthread Programming in VS2010, you will need the following:
1) pthreadVC2.lib
2) pthreadVC2.dll
3) semaphore.h, sched.h, pthread.h

All pthread source codes, *.lib, *.dll, *.h will be available in a link from -> https://sourceware.org/pthreads-win32/#download
(Download according to you system architecture i.e. x86 or x64)

Now, let us try a hello world program;


  • Paste *.h files in C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\
  • *.dll files will be required in the ...\Debug\ folded inside projects file structure.
  • Open VS2010
  • File -> New -> Project
  • Visual C++ -> General -> Empty Project
  • In the solution explorer,
    • right click 'source files' -> add -> new item
    • Visual C++ -> Code -> C++ File (.cpp)
    • Enter 'name' -> Add
  • Now type the following code in the *.cpp file:
#include<iostream>
#include<pthread.h>
#include<errno.h>
#include<string.h>
using namespace std;

void* thread_func(void* arg)
{
cout<<endl<<" Thread created with "<<(long) arg<<" as ID\n";
return NULL;
}

void printError(char* msg,int status,char* filename,int lineno)
{
cout<<endl<<" Error msg: "<<msg<<" : "<<strerror(status)<<" in file "<<filename<<" at line "<<lineno;
}

int main()
{
cout<<endl<<"hello world"<<endl;
pthread_t th;
pthread_attr_t th_attr;
int status=pthread_attr_init(&th_attr);
if(status)
{
printError("Attribute initiation error",status,__FILE__,__LINE__);
exit(EXIT_FAILURE);
}
status=pthread_attr_setscope(&th_attr,PTHREAD_SCOPE_SYSTEM);
if(status)
{
printError("Attribute Scope setting error",status,__FILE__,__LINE__);
exit(EXIT_FAILURE);
}
status=pthread_create(&th,&th_attr,thread_func,(void*)1L);
if(status)
{
printError("Thread Creation error",status,__FILE__,__LINE__);
exit(EXIT_FAILURE);
}
status=pthread_attr_destroy(&th_attr);
if(status)
{
printError("Attribute Destroy error",status,__FILE__,__LINE__);
exit(EXIT_FAILURE);
}
status=pthread_join(th,(void**)NULL);
if(status)
{
printError("Thread joining error",status,__FILE__,__LINE__);
exit(EXIT_FAILURE);
}
cout<<endl<<"Now control passed into main(), exiting..."<<endl;
return 0;
}

  • right click project name -> Properties -> Configuration Properties -> Linker
  • Input -> Additional Dependencies
  • Pop down menu -> Edit -> type 'pthreadVC2.lib' -> Ok -> Ok

__FILE__ is a preprocessor macro that expands to full path to the current file. __FILE__ is useful when generating log statements, error messages intended for programmers, when throwing exceptions, or when writing debugging code.

Possible Errors:
-----------------------


  • error LNK2019: unresolved external symbol __imp_ pthread_attr_destroy referenced in function
    • This error is because we are using a x64 architecture library and building x32 solution or vice-versa
    • This can be rectified by either downloading library files for the solution intended or changing the output solution type according to the library files we have
    • symbol__imp_pthread -> x86
    • symbol__imp__pthread -> x64
\
  • error LNK1104: cannot open file 'pthreadVC2.lib'
    • sometimes, even after linking pthreadVC2.lib in Additional Dependencies, we will get this error
    • this can be rectified by going to 'Configuration Properties' -> 'VC++ Directories' -> 'Library Directories' -> pop down arrow -> Edit
    • See the list of path by clicking on 'Macros'
    • Try to pthreadVC2.lib in the path mention over there
    • e.g:-
      • $(VCInstallDir)lib\amd64 - C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC
      • so add in 'C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\amd64'

pthread_create, pthread_attr_init
pthread_attr_setscope
pthread_attr_destroy

pthread_join

mutex

pthread_self, pthread_equal

pthread_cancel, pthread_exit

pthread_detach

pthread_cond_signal()- awakens single thread in pthread_cond_wait()/pthread_cond_timewait(). But in case of multiple thread waiting, they are awakened according to scheduling priority + FIFO

pthread_cond_broadcast() - awakens all threads in waiting
the thread that issues signal/broadcast call, holds the mutex at time of call, but must release it after the call. It wakes up a waiting thread, which regains the control of the mutex.

mutex
conditional variables
Reader/Writer Locks