一直对C++多线程一知半解,感觉没有实际进入过C++多线程的世界,因此想从头开始慢慢真正进入C++多线程,真正了解多线程。因为我也想了解Linux下的C++ 编程,因此我也会在Linux平台下进行编写代码并验证。文章里面会借鉴一些网上优秀的代码和讲解,但买一行代码我都会自己敲一遍,学习和借鉴是一起的,但代码必须是自己一行一行写的才行。这里的开头也是希望自己能记住自己的初衷!
#include
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
);
lpThreadAttributes [in, optional]
A pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpThreadAttributes is NULL, the handle cannot be inherited.(该参数是一个指向 SECURITY_ATTRIBUTES 的指针,这个指针决定创建的该线程句柄是否被子进程继承,如果该参数为NULL,则表示该句柄不能被继承)。
dwStackSize [in]
The initial size of the stack, in bytes. The system rounds this value to the nearest page. If this parameter is zero, the new thread uses the default size for the executable(初始化栈的大小,单位为byte,系统会在最近的一页取得该大小内存。如果该参数为0,则创建的线程会采用默认的大小)。
lpStartAddress [in]
A pointer to the application-defined function to be executed by the thread. This pointer represents the starting address of the thread(线程函数的指针,该指代表该线程的入口地址)。
lpParameter [in, optional]
A pointer to a variable to be passed to the thread(线程函数的参数指针)。
dwCreationFlags [in]
The flags that control the creation of the thread(控制该线程的标记,实际就是该线程被创建后接下来的动作是被挂起还是立即执行,该参数为0表示立即执行,0x00000004 CREATE_SUSPENDED表示挂起)。
lpThreadId [out, optional]
A pointer to a variable that receives the thread identifier. If this parameter is NULL, the thread identifier is not returned(该线程ID的指针,如果为NULL则不返回线程ID的值)。
若线程创建成功,则返回线程句柄。
#include
#include
using namespace std;
unsigned long WINAPI Fun(LPVOID lpParamter)
{
int iRunTime = 0;
while(++iRunTime<100)//执行100次跳出
{
cout << "Fun() is running!"<10);
}
ExitThread(-1);
}
int main()
{
int iRunTime = 0;
unsigned long ulThreadId = 0;
HANDLE hThread = CreateThread(NULL, 0, Fun, NULL, 0, &ulThreadId);
while(++iRunTime<100) //执行100次跳出
{
cout << "main() is running, Thread id is " << ulThreadId <10);
}
system("pause");
return 0;
}
执行结果:
从打印的第一行看出来主线程main()执行到一半的时候,子线程Fun开始执行,子线程执行到一半的时候,主线程又开始执行,这是因为主线程main()和子线程同时抢夺“屏幕”这一项资源导致的,CPU会轮流给这2个线程相同的时间片去执行自己的内容,时间到后切换到另一个线程去执行,因此导致了这样的结果。另外我们可以看到子线程的ID为7920,目前这个ID对我们貌似没有什么用。
#include
int pthread_create(pthread_t *tidp, const pthread_attr_t *attr,
(void*)(*start_rtn)(void*), void *arg);
tidp:第一个参数为指向线程标识符的指针。
attr:第二个参数用来设置线程属性。
start_rtn:第三个参数是线程运行函数的起始地址。
arg:最后一个参数是运行函数的参数。
-pthread
若线程创建成功,则返回0。若线程创建失败,则返回出错编号,并且*thread中的内容是未定义的;返回成功时,由tidp指向的内存单元被设置为新创建线程的线程ID。
因为pthread并非Linux系统的默认库,而是POSIX线程库。在Linux中将其作为一个库来使用,因此加上 -lpthread(或-pthread)以显式链接该库。函数在执行错误时的错误信息将作为返回值返回,并不修改系统全局变量errno,当然也无法使用perror()打印错误信息。
g++ -o example example.c -lpthread
#include
#include
using namespace std;
static const int g_iRunTime = 5000;
void* Fun(void* ptr)
{
int iRunTime = 0;
while(++iRunTime< g_iRunTime)
{
cout<< "Fun() is running!" << endl;
usleep(10000);
}
}
int main()
{
pthread_t hHandle;
int iRet = pthread_create(&hHandle, NULL, Fun, NULL); //create a thread;
if(0 != iRet)
{
cout << "Create thread failed!" << endl;
}
sleep(1);
int iRunTime = 0;
while(++iRunTimecout << "main is running! " <10000);
}
sleep(1000);
return 0;
}
这里也造成了输出空行的情况,也是由于“屏幕”资源争夺造成。这里多数一句,在Linux下我使用了打印5000次的情况才勉强造成一次输出空行,而Windows平台下100行打印就能出现多次,感觉上Linux对资源的分配比Windows更加合理,造成冲突的几率也比Windows低很多。