In this article, I'm trying to show some differences between Windows and Linux thread creation and their respective usage.
Creating Threads:
1.
a. In Windows: CreateThread() API is used to create a thread to execute within the virtual address space of the calling process.
b. In Linux: pthread_create() function creates a thread.
Function Signature:
// Windows
HANDLE WINAPI CreateThread(
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ SIZE_T dwStackSize,
_In_ LPTHREAD_START_ROUTINE lpStartAddress,
_In_opt_ LPVOID lpParameter,
_In_ DWORD dwCreationFlags,
_Out_opt_ LPDWORD lpThreadId
);
Function Signature:
// Linux
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg);
In Windows: We can pass stack size in bytes if required to the same CreateThread() API.
In Linux: The stack size is set in the pthread attributes object; that is, the parameter attr of type pthread_attr_t is passed to the library call pthread_create().
This object needs to be initialized by the call pthread_attr_init() before any attributes are set.
The attribute object is destroyed using the call pthread_attr_destroy().
The stack size is set using the call pthread_attr_setstacksize(): int pthread_attr_setstacksize(pthread_attr_t *threadAttr, int stack_size);
This article uses default thread attributes to create threads on Windows and Linux.
In Windows: Used WaitForMultipleObjects() API to force main() to wait until all threads execution are done.
In Linux: Used pthread_join() to achieve the same.
The following code snippets do the same stuff on Windows and Linux but there are some differences from a programming point of view.
Code Windows:
=============
#include < windows.h >
#include < stdio.h >
#define MAX_THREADS 2
struct MyData
{
char name[20];
char thread[20];
};
DWORD WINAPI MyThreadFunction( LPVOID lpParam );
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hThread[2] = {NULL};
DWORD dwThreadId;
struct MyData mData1;
struct MyData mData2;
strcpy(mData1.name, "Testing - 1");
strcpy(mData1.thread, "Thread - 1");
strcpy(mData2.name, "Testing - 2");
strcpy(mData2.thread, "Thread - 2");
hThread[0] = CreateThread(
NULL, // Default Security Attributes
0, // Use Default Stack size
MyThreadFunction, // Thread function name
&mData1, // Argument to thread function
0, // Use default creation flags
&dwThreadId
);
if(NULL == hThread[0])
{
printf("CreateThread failed for Thread 1\n");
}
hThread[1] = CreateThread(
NULL, // Default Security Attributes
0, // Use Default Stack size
MyThreadFunction, // Thread function name
&mData2, // Argument to thread function
0, // Use default creation flags
&dwThreadId
);
if(NULL == hThread[1])
{
printf("CreateThread failed for Thread 2\n");
}
// Wait until all threads have terminated.
WaitForMultipleObjects(MAX_THREADS, hThread, TRUE, INFINITE);
CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
return 0;
}
DWORD WINAPI MyThreadFunction( LPVOID lpParam )
{
struct MyData *p = (struct MyData *)lpParam;
printf("Name: %s\n", p->name);
printf("Thread: %s\n", p->thread);
printf("+++++++++++++++++++++++++++++\n");
return 0;
}
Code Linux:
=============
#include < pthread.h >
#include < stdio.h >
#include < string.h >
struct mystruct
{
char name[20];
char thread[20];
};
void *Print_Details(void *param)
{
/*Cast the pointer to right type */
struct mystruct* p = (struct mystruct*) param;
printf("Name: %s\n", p->name);
printf("Thread: %s\n", p->thread);
printf("+++++++++++++++++++\n");
return NULL;
}
/* Main program */
int main()
{
pthread_t thread1;
pthread_t thread2;
struct mystruct args1;
struct mystruct args2;
/* Create new thread */
strcpy(args1.name, "Testing - 1");
strcpy(args1.thread, "Thread - 1");
pthread_create(&thread1, NULL, &Print_Details, &args1);
/* Create another new thread */
strcpy(args2.name, "Testing - 2");
strcpy(args2.thread, "Thread - 2");
pthread_create(&thread2, NULL, &Print_Details, &args2);
/* Ensure the First thread has finished */
pthread_join(thread1, NULL);
/* Ensure the second thread has finished */
pthread_join(thread2, NULL);
/* Now safe to return main */
return 0;
}
Reference Windows: http://msdn.microsoft.com/en-us/library/ms682453%28VS.85%29.aspx
Reference Linux: http://publib.boulder.ibm.com/infocenter/iseries/v5r4/index.jsp?topic=%2Fapis%2Fusers_14.htm
Creating Threads:
1.
a. In Windows: CreateThread() API is used to create a thread to execute within the virtual address space of the calling process.
b. In Linux: pthread_create() function creates a thread.
Function Signature:
// Windows
HANDLE WINAPI CreateThread(
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ SIZE_T dwStackSize,
_In_ LPTHREAD_START_ROUTINE lpStartAddress,
_In_opt_ LPVOID lpParameter,
_In_ DWORD dwCreationFlags,
_Out_opt_ LPDWORD lpThreadId
);
Function Signature:
// Linux
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg);
In Windows: We can pass stack size in bytes if required to the same CreateThread() API.
In Linux: The stack size is set in the pthread attributes object; that is, the parameter attr of type pthread_attr_t is passed to the library call pthread_create().
This object needs to be initialized by the call pthread_attr_init() before any attributes are set.
The attribute object is destroyed using the call pthread_attr_destroy().
The stack size is set using the call pthread_attr_setstacksize(): int pthread_attr_setstacksize(pthread_attr_t *threadAttr, int stack_size);
This article uses default thread attributes to create threads on Windows and Linux.
In Windows: Used WaitForMultipleObjects() API to force main() to wait until all threads execution are done.
In Linux: Used pthread_join() to achieve the same.
The following code snippets do the same stuff on Windows and Linux but there are some differences from a programming point of view.
Code Windows:
=============
#include < windows.h >
#include < stdio.h >
#define MAX_THREADS 2
struct MyData
{
char name[20];
char thread[20];
};
DWORD WINAPI MyThreadFunction( LPVOID lpParam );
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hThread[2] = {NULL};
DWORD dwThreadId;
struct MyData mData1;
struct MyData mData2;
strcpy(mData1.name, "Testing - 1");
strcpy(mData1.thread, "Thread - 1");
strcpy(mData2.name, "Testing - 2");
strcpy(mData2.thread, "Thread - 2");
hThread[0] = CreateThread(
NULL, // Default Security Attributes
0, // Use Default Stack size
MyThreadFunction, // Thread function name
&mData1, // Argument to thread function
0, // Use default creation flags
&dwThreadId
);
if(NULL == hThread[0])
{
printf("CreateThread failed for Thread 1\n");
}
hThread[1] = CreateThread(
NULL, // Default Security Attributes
0, // Use Default Stack size
MyThreadFunction, // Thread function name
&mData2, // Argument to thread function
0, // Use default creation flags
&dwThreadId
);
if(NULL == hThread[1])
{
printf("CreateThread failed for Thread 2\n");
}
// Wait until all threads have terminated.
WaitForMultipleObjects(MAX_THREADS, hThread, TRUE, INFINITE);
CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
return 0;
}
DWORD WINAPI MyThreadFunction( LPVOID lpParam )
{
struct MyData *p = (struct MyData *)lpParam;
printf("Name: %s\n", p->name);
printf("Thread: %s\n", p->thread);
printf("+++++++++++++++++++++++++++++\n");
return 0;
}
Code Linux:
=============
#include < pthread.h >
#include < stdio.h >
#include < string.h >
struct mystruct
{
char name[20];
char thread[20];
};
void *Print_Details(void *param)
{
/*Cast the pointer to right type */
struct mystruct* p = (struct mystruct*) param;
printf("Name: %s\n", p->name);
printf("Thread: %s\n", p->thread);
printf("+++++++++++++++++++\n");
return NULL;
}
/* Main program */
int main()
{
pthread_t thread1;
pthread_t thread2;
struct mystruct args1;
struct mystruct args2;
/* Create new thread */
strcpy(args1.name, "Testing - 1");
strcpy(args1.thread, "Thread - 1");
pthread_create(&thread1, NULL, &Print_Details, &args1);
/* Create another new thread */
strcpy(args2.name, "Testing - 2");
strcpy(args2.thread, "Thread - 2");
pthread_create(&thread2, NULL, &Print_Details, &args2);
/* Ensure the First thread has finished */
pthread_join(thread1, NULL);
/* Ensure the second thread has finished */
pthread_join(thread2, NULL);
/* Now safe to return main */
return 0;
}
Reference Windows: http://msdn.microsoft.com/en-us/library/ms682453%28VS.85%29.aspx
Reference Linux: http://publib.boulder.ibm.com/infocenter/iseries/v5r4/index.jsp?topic=%2Fapis%2Fusers_14.htm
Comments