C++多线程特点与缺点(C++多线程相关)

mutithread主要特点:

1、对于一个程序的地址空间是共享的
2、代码段共享,数据不能共享
3、mutithread单核会有线程切换,多核没有仅仅是数据处理就可以
4、不同操作系统接口比较统一
5、用多线程既能快速处理数据又能快速进行计算

缺点:

代码容易出错,mutithread类似于goto
可能出现的问题包括:
1、死锁 (两个线程相互等待对方释放资源)
2、乱序
3、并发访问数据造成的问题(问题查错困难)
4、低效率

C++11给我们带来的新概念

1、高阶接口:(async,future) async:两件事情一起做
2、低阶接口:(thread,mutex)

以下是关于多线程简单的一个例子:

void helloWorld(){
	std::cout<<"hello world\n";
}
int main(){
	//开启一个线程
	std::thread t(helloWorld);
	//std::cout<<"hello main thread\n";
	//线程的终结
	t.join();
}

C++多线程特点与缺点(C++多线程相关)_第1张图片
开启线程可以传入函数,不影响main函数正常运行
主线程和子线程两者运行速度未知,先后顺序未知
以join等待子线程工作完成,等子线程完成之后才会继续执行main

以下是关于多线程具体解析:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
//enum memory_order {
//
//  memory_order_relaxed,
//  memory_order_consume,
//  memory_order_acquire,
//  memory_order_release,
//  memory_order_acq_rel,
//  memory_order_seq_cst
//};

// 为什么用多线程来做服务器?
// (1)当前的机器的单核红利已经结束了
// process(linux fork windows CreateProcess, signal) thread (POSIX threads)
// (2)多线程拥有自身的优势
// (3)API日益成熟,操作系统和标准库都已经支持了多线程
// 要在数据IO和计算找到平衡点
// 多线程的编程,mutilthread goto
// 可能的问题包括:
// (1)死锁;
// (2)乱序
// (3)并发访问数据造成的问题;
// (4)低效率

// c++11给我们带来的新概念
// (1)高阶接口;(async, future)
// (2)低阶接口;(thread, mutex)
//
//
//沉重的计算方法
double caculate(double v) {
  if (v <= 0)
    return v;
	std::this_thread::sleep_for(std::chrono::milliseconds(10));
  // 实际上计算机算这个东西是很快的,但是我们假装它算的很慢 :)
  return sqrt((v * v + std::sqrt((v - 5) * (v + 2.5)) / 2.0) / v);
}
// for_each
template <typename Iter, typename Fun>
double visitRange(std::thread::id id, Iter iterBegin, Iter iterEnd, Fun func) {
	auto curId = std::this_thread::get_id();
	if(id == curId)
		std::cout << curId << " hello main thread\n";
	else std::cout << curId << " hello work thread\n";
  double v = 0;
  for (auto iter = iterBegin; iter != iterEnd; ++iter) {
    v += func(*iter);
  }
  return v;
}

class Counter {
public:
	void addCountAndResouce(int r) {
		std::lock_guard<std::mutex> lock(m_mutex);
		addCount();
		addResource(r);
	}
	int count() const {
		std::lock_guard<std::mutex> lock(m_mutex);
		return m_count;
	}
	int aveResource() {
		std::lock_guard<std::mutex> lock(m_mutex);
		if (m_count == 0) {
			return 1;
		}
		return m_totalResource / m_count;
	}
  Counter() : m_count{0},m_totalResource{0} {}

private:
	int m_count;
	int m_totalResource;
	mutable std::mutex m_mutex;
	void addResource(int r) {m_totalResource++;}
  void addCount() { m_count++; } // 写入寄存器 寄存器加1 写入内存
	// ++ -- + - * /
	// expert fetch_add fetch_sub
	//int m_count;
};

int work(int a) {
  // do some thing
  return a + a;
}

void debugPrintInfo(Counter& c) {
	std::cout << c.aveResource() << std::endl;
}


template <class Iter>
void realWork(Counter &c, double &totalValue, Iter b, Iter e) {
  for (; b != e; ++b) {
		try {
    totalValue += work(*b);
		// print some vaule
	//	debugPrintInfo(c);
    c.addCountAndResouce(1);
		} catch(...) {
		}
  }
}
void printAll(int a, int b, int c) {
	std::cout << a << " " << b << " " << c << std::endl;
}

void add(int a, int b, int& c) {
	c = a + b;
}

void printString(const std::string& info, const std::string& info2) {
	std::cout << "hello " << info << " " << info2 << "\n";
}

void testThreadInit() {
	int a = 3;
	int b = 4;
	int c = 5;
	std::thread t([=]{printAll(a,b,c);});
	t.join();
	std::thread t2(printAll, a, b, c);
	t2.join();

	std::thread t3([=, &c]{add(a,b,c);});
	t3.join();
	std::cout << "after add " << c << std::endl;
	std::thread t4(add, a, b, std::ref(c));
	t4.join();

	std::string abc("abc");
	std::string def("def");

	std::thread t5([&]{printString(abc,def);});
	t5.join();
	std::thread t6(printString, abc, def);
	t6.join();
	std::thread t7(printString, std::cref(abc), std::cref(def));
	t7.join();


}

bool printStep(Counter &c, int maxCount) {
  auto count = c.count();
  if (count == maxCount) {
    std::cout << " ok finished \n";
		return true;
	}
	return false;
}


struct BankAccount {
	BankAccount(int b) : Balance(b) {}
	int Balance;
	std::mutex Mutex;
};

template<typename T>
class Lock {
	public:
		Lock(T& m) : m_mutex(m) { m.lock();}
		~Lock() { m_mutex.unlock();}
	private:
		T& m_mutex;
};

void transferMoney(BankAccount &a, BankAccount &b, int money) {
	std::lock(a.Mutex, b.Mutex /* ..... */);
	std::lock_guard<std::mutex> lockA(a.Mutex, std::adopt_lock);
	std::lock_guard<std::mutex> lockB(b.Mutex, std::adopt_lock);

	if (a.Balance <= money)
		return;
	a.Balance -= money;
	b.Balance += money;
//  if (&a == &b)
//    return;
//  if (&(a.Mutex) < &(b.Mutex)) {
//    std::lock_guard lockA(a.Mutex);
//    std::lock_guard lockB(b.Mutex);
//
//    if (a.Balance <= money)
//      return;
//    a.Balance -= money;
//    b.Balance += money;
//  } else {
//    std::lock_guard lockA(b.Mutex);
//    std::lock_guard lockB(a.Mutex);
//    if (a.Balance <= money)
//      return;
//    a.Balance -= money;
//    b.Balance += money;
//  }
}

// BankAccount alice(100);
// BankAccount bob(100);
// threa1
// transferMoney(alice, bob, 10); // when call lockB
// thread2
// transferMoney(bob, alice, 10); // when call lockB



int main() {
	//testThreadInit();
  unsigned int n = std::thread::hardware_concurrency();
  std::cout << n << " concurrent threads are supported.\n";
	std::vector<int> vec;
	double totalValue = 0;
	for(int i = 0; i < 10000000; ++i) {
		vec.push_back(rand() % 100);
	}
	Counter counter;
	realWork(counter, totalValue, vec.begin(), vec.end());
	// do work
	std::cout << "total times: " << counter.count() << " " << totalValue<< std::endl;

	totalValue = 0;
	Counter counter2;
	std::thread printCount([&counter2] {
			while (!printStep(counter2, 10000000))
			;
			});
	auto iter = vec.begin() + (vec.size() / 3);
	auto iter2 = vec.begin() + (vec.size() / 3 * 2);
	std::thread b([&counter2, &totalValue, iter, iter2] {
			realWork(counter2, totalValue, iter, iter2);
			});
	auto end = vec.end();
	double totalC = 0;
	std::thread c([&counter2, &totalC, iter2, end] {
			realWork(counter2, totalC, iter2, end);
			});

	double totalM = 0;
	realWork(counter2, totalM, vec.begin(), iter);
	b.join();
	c.join();
	auto realTotalCount = counter2.count();
	totalValue += totalC + totalM;
	std::cout << "total times use multithread: " << realTotalCount << " " << totalValue << std::endl;
	printCount.join();
	// (1) 如果没有必要的话,线程间不要共享资源
}

你可能感兴趣的:(C++asio服务器开发)