TinyThread计数器 - 便携式c++0和c++11线程间通信变得简单
TinyThread counter - portable c++0 and c++11 inter thread communication made simple
我看到这个例子是TinyThread c++库的一部分,并注意到它如何在辅助线程上增加gCount,然后由主线程打印。参见测试 5
/* -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; -*-
Copyright (c) 2010-2012 Marcus Geelnard
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include <iostream>
#include <list>
#include <tinythread.h>
#include <fast_mutex.h>
using namespace std;
using namespace tthread;
// HACK: Mac OS X and early MinGW do not support thread-local storage
#if defined(__APPLE__) || (defined(__MINGW32__) && (__GNUC__ < 4))
#define NO_TLS
#endif
// Thread local storage variable
#ifndef NO_TLS
thread_local int gLocalVar;
#endif
// Mutex + global count variable
mutex gMutex;
fast_mutex gFastMutex;
int gCount;
// Condition variable
condition_variable gCond;
// Thread function: Thread ID
void ThreadIDs(void * aArg)
{
cout << " My thread id is " << this_thread::get_id() << "." << endl;
}
#ifndef NO_TLS
// Thread function: Thread-local storage
void ThreadTLS(void * aArg)
{
gLocalVar = 2;
cout << " My gLocalVar is " << gLocalVar << "." << endl;
}
#endif
// Thread function: Mutex locking
void ThreadLock(void * aArg)
{
for(int i = 0; i < 10000; ++ i)
{
lock_guard<mutex> lock(gMutex);
++ gCount;
}
}
// Thread function: Mutex locking
void ThreadLock2(void * aArg)
{
for(int i = 0; i < 10000; ++ i)
{
lock_guard<fast_mutex> lock(gFastMutex);
++ gCount;
}
}
// Thread function: Condition notifier
void ThreadCondition1(void * aArg)
{
lock_guard<mutex> lock(gMutex);
-- gCount;
gCond.notify_all();
}
// Thread function: Condition waiter
void ThreadCondition2(void * aArg)
{
cout << " Wating..." << flush;
lock_guard<mutex> lock(gMutex);
while(gCount > 0)
{
cout << "." << flush;
gCond.wait(gMutex);
}
cout << "." << endl;
}
// Thread function: Yield
void ThreadYield(void * aArg)
{
// Yield...
this_thread::yield();
}
// Thread function: Detach
void ThreadDetach(void * aArg)
{
// We don't do anything much, just sleep a little...
this_thread::sleep_for(chrono::milliseconds(100));
}
// This is the main program (i.e. the main thread)
int main()
{
// Test 1: Show number of CPU cores in the system
cout << "PART I: Info" << endl;
cout << " Number of processor cores: " << thread::hardware_concurrency() << endl;
// Test 2: thread IDs
cout << endl << "PART II: Thread IDs" << endl;
{
// Show the main thread ID
cout << " Main thread id is " << this_thread::get_id() << "." << endl;
// Start a bunch of child threads - only run a single thread at a time
thread t1(ThreadIDs, 0);
t1.join();
thread t2(ThreadIDs, 0);
t2.join();
thread t3(ThreadIDs, 0);
t3.join();
thread t4(ThreadIDs, 0);
t4.join();
}
// Test 3: thread local storage
cout << endl << "PART III: Thread local storage" << endl;
#ifndef NO_TLS
{
// Clear the TLS variable (it should keep this value after all threads are
// finished).
gLocalVar = 1;
cout << " Main gLocalVar is " << gLocalVar << "." << endl;
// Start a child thread that modifies gLocalVar
thread t1(ThreadTLS, 0);
t1.join();
// Check if the TLS variable has changed
if(gLocalVar == 1)
cout << " Main gLocalID was not changed by the child thread - OK!" << endl;
else
cout << " Main gLocalID was changed by the child thread - FAIL!" << endl;
}
#else
cout << " TLS is not supported on this platform..." << endl;
#endif
// Test 4: mutex locking
cout << endl << "PART IV: Mutex locking (100 threads x 10000 iterations)" << endl;
{
// Clear the global counter.
gCount = 0;
// Start a bunch of child threads
list<thread *> threadList;
for(int i = 0; i < 100; ++ i)
threadList.push_back(new thread(ThreadLock, 0));
// Wait for the threads to finish
list<thread *>::iterator it;
for(it = threadList.begin(); it != threadList.end(); ++ it)
{
thread * t = *it;
t->join();
delete t;
}
// Check the global count
cout << " gCount = " << gCount << endl;
}
// Test 5: fast_mutex locking
cout << endl << "PART V: Fast mutex locking (100 threads x 10000 iterations)" << endl;
{
// Clear the global counter.
gCount = 0;
// Start a bunch of child threads
list<thread *> threadList;
for(int i = 0; i < 100; ++ i)
threadList.push_back(new thread(ThreadLock2, 0));
// Wait for the threads to finish
list<thread *>::iterator it;
for(it = threadList.begin(); it != threadList.end(); ++ it)
{
thread * t = *it;
t->join();
delete t;
}
// Check the global count
cout << " gCount = " << gCount << endl;
}
// Test 6: condition variable
cout << endl << "PART VI: Condition variable (40 + 1 threads)" << endl;
{
// Set the global counter to the number of threads to run.
gCount = 40;
// Start the waiting thread (it will wait for gCount to reach zero).
thread t1(ThreadCondition2, 0);
// Start a bunch of child threads (these will decrease gCount by 1 when they
// finish)
list<thread *> threadList;
for(int i = 0; i < 40; ++ i)
threadList.push_back(new thread(ThreadCondition1, 0));
// Wait for the waiting thread to finish
t1.join();
// Wait for the other threads to finish
list<thread *>::iterator it;
for(it = threadList.begin(); it != threadList.end(); ++ it)
{
thread * t = *it;
t->join();
delete t;
}
}
// Test 7: yield
cout << endl << "PART VII: Yield (40 + 1 threads)" << endl;
{
// Start a bunch of child threads
list<thread *> threadList;
for(int i = 0; i < 40; ++ i)
threadList.push_back(new thread(ThreadYield, 0));
// Yield...
this_thread::yield();
// Wait for the threads to finish
list<thread *>::iterator it;
for(it = threadList.begin(); it != threadList.end(); ++ it)
{
thread * t = *it;
t->join();
delete t;
}
}
// Test 8: sleep
cout << endl << "PART VIII: Sleep (10 x 100 ms)" << endl;
{
// Sleep...
cout << " Sleeping" << flush;
for(int i = 0; i < 10; ++ i)
{
this_thread::sleep_for(chrono::milliseconds(100));
cout << "." << flush;
}
cout << endl;
}
// Test 9: detach
cout << endl << "PART IX: Detach" << endl;
{
thread t(ThreadDetach, 0);
t.detach();
cout << " Detached from thread." << endl;
}
}
所以我尝试制作自己的代码,但主线程不仅看不到变量增量,而且当我将睡眠添加到工作线程时,它不再尝试在主线程上打印变量。由于这两个问题,工作线程也永远不会退出。
#include <iostream>
#include <list>
#include "tinythread.h"
#include "fast_mutex.h"
using namespace std;
using namespace tthread;
fast_mutex workerThreadMutex;
bool killThread = false;
int number = 0;
void workerThread(void * aArg)
{
bool running = true;
int number = 0;
while(running)
{
lock_guard<fast_mutex> lock(workerThreadMutex);
number++;
cout << "secondThread::" << number << endl;
this_thread::sleep_for(chrono::milliseconds(1000));
if(killThread)
running =true;
}
}
int main()
{
thread* wThread = new thread(workerThread, 0);
bool running = true;
while(running)
{
this_thread::sleep_for(chrono::milliseconds(100));
if(workerThreadMutex.try_lock())
{
cout << "mainThread::" << number << endl;
if(number == 100)
{
killThread = true;
running = false;
}
workerThreadMutex.unlock();
}
}
wThread->join();
delete wThread;
return 0;
}
你能帮忙吗?
编辑:对我的代码进行了更改
编辑:修复了局部变量问题,它现在可以工作了,除了没有检测到终止线程布尔值,因此辅助线程(工作线程(没有退出。
编辑:修复了局部变量的问题
编辑:修复了睡眠问题
编辑:修复了问题杀戮线程
编辑:所有问题都已修复
#include <iostream>
#include <list>
#include "tinythread.h"
#include "fast_mutex.h"
using namespace std;
using namespace tthread;
fast_mutex workerThreadMutex;
bool killThread = false;
int number = 0;
bool running = true;
void workerThread(void * aArg)
{
while(running)
{
{
lock_guard<fast_mutex> lock(workerThreadMutex);
number++;
if(killThread)
running =false;
}
this_thread::sleep_for(chrono::milliseconds(50));
}
}
int main()
{
thread* wThread = new thread(workerThread, 0);
while(running)
{
this_thread::sleep_for(chrono::milliseconds(100));
if(workerThreadMutex.try_lock())
{
cout << "mainThread::" << number << endl;
if(number > 100)
{
killThread = true;
//running = false;
}
workerThreadMutex.unlock();
}
}
wThread->join();
delete wThread;
return 0;
}
编辑:进一步修改以显示可移植的C ++ 11友好的线程间通信
#include <iostream>
#include <sstream>
#include "tinythread.h"
#include "fast_mutex.h"
using namespace std;
using namespace tthread;
fast_mutex workerThreadMutex;
bool killThread = false;
int number = 0;
bool running = true;
string message = "";
void workerThread(void * aArg)
{
while(running)
{
{
lock_guard<fast_mutex> lock(workerThreadMutex);
if(message=="")
{
number++;
ostringstream Convert;
Convert << number;
message = Convert.str();
}
if(killThread)
running =false;
}
this_thread::sleep_for(chrono::milliseconds(1));
}
}
int main()
{
thread* wThread = new thread(workerThread, 0);
bool stopMainThreadLoop = false;
while(!stopMainThreadLoop)
{
this_thread::sleep_for(chrono::milliseconds(10));
if(workerThreadMutex.try_lock())
{
//cout << "mainThread::" << number << endl;
cout << "mainThread::" << message << endl;
//if(number > 100)
if(message == "100")
{
killThread = true;
stopMainThreadLoop = true;
}
message = "";
workerThreadMutex.unlock();
}
}
wThread->join();
delete wThread;
return 0;
}
看看你的代码的这一部分
int number = 0; // Global variable, i.e. will be used by main
void workerThread(void * aArg)
{
bool running = true;
int number = 0; // Local variable, i.e. will be used by in the function
因此,main
正在使用一个变量,而函数(也称为线程(正在使用另一个变量。因此,main 看不到任何增量。
只需删除局部变量即可。
对于睡眠部分
我认为问题是你在保持互斥锁的同时睡觉。
试试这个:
void workerThread(void * aArg)
{
bool running = true;
//---------------------- int number = 0;
while(running)
{
{
lock_guard<fast_mutex> lock(workerThreadMutex);
number++;
//cout << "secondThread::" << number << endl;
if(killThread)
running =true;
}
this_thread::sleep_for(chrono::milliseconds(1000));
}
}
对于杀戮:
试试这个
if(number >= 100) // Changed
{
killThread = true;
running = false;
}
函数内部
if(killThread)
running =true; // Should be false
相关文章:
- 在c++中用vector填充一个简单的动态数组
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的简单if-else语句是如何无法访问的代码
- 使用简单类型列表实现的指数编译时间.为什么
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 如何在BST的这个简单递归实现中消除警告
- 是否可以使用winusb同时与多个相同的usb设备进行通信
- 一种在C++中读取TXT配置文件的简单方法
- 关于简单C++函数(is_palindrome)的逻辑的问题
- 显示错误输出的简单数组排序程序
- 混淆了如何使用IDL与Ethovision进行通信
- 当无法使用模板和宏时,生成类型变体C++代码的最简单方法是什么?
- 退出简单while循环时出现问题
- 为什么简单的算术减法在"if"条件下不起作用?
- 使用boost :: asio进行简单的UDP通信
- 一个使用QtUdpSocket的简单通信c / s应用程序
- 使用UNIX套接字C++客户端与Node.js服务器通信的简单示例
- 使用Boost.ASIO与服务器进行简单的网络tcp通信
- TinyThread计数器 - 便携式c++0和c++11线程间通信变得简单
- 在 Windows 上的 C++ 中实现强大、简单(且快速)的进程间通信