C++ 多线程学习总结

C++ 多线程

  • 头文件
#include 

创建线程 thread

jion与detach方式的区别

  • jion方式:必须等待已经创建的子线程任务执行完毕,才会继续往下执行。
    示例:
void my_func1_task()
{
	cout << "I am my_func1_task" << endl;
	cout << "my_func1_task end" << endl;
}

void my_func2_task(int x)
{
	cout << "I am my_func2_task" << endl;
	while (x--)
	{
		cout << "x:" << x << ";";
		sleep(1);
	}
	cout << endl;
	cout << "my_func2_task end" << endl;
}

int main(int argc, char *argv[])
{
	cout << "this is main()" << endl;
	thread thread_1(my_func1_task);
	//等待线程1完成
	thread_1.join();
	
	thread thread_2(my_func2_task, 10);
	//等待线程2完成
	thread_2.join();
	cout << "thread end" << endl;

	cout << "main end" << endl;
	return 0;
}

测试结果:
C++ 多线程学习总结_第1张图片

  • detach方式:启动的子线程自主在后台运行,当前主线程代码继续往下执行,无需等待子线程结束。
    注:该种情况下,主线程一般会进入while(1)循环执行主线程逻辑,否则整个进程会结束。
    示例:
void my_func1_task()
{
	cout << "I am my_func1_task" << endl;
	cout << "my_func1_task end" << endl;
}

void my_func2_task(int x)
{
	cout << "I am my_func2_task" << endl;
	while (x--)
	{
		cout << "x:" << x << ";";
		sleep(1);
	}
	cout << endl;
	cout << "my_func2_task end" << endl;
}

int main(int argc, char *argv[])
{
	cout << "this is main()" << endl;
	thread thread_1(my_func1_task);
	thread_1.detach();
	
	thread thread_2(my_func2_task, 10);
	thread_2.detach();
	cout << "thread end" << endl;

	cout << "main end" << endl;
	return 0;
}

测试结果:
在这里插入图片描述

互斥锁 mutex

  • 头文件
#include 

lock和unlock

不上锁测试示例:

int g_count = 10;

void my_func1_task()
{
	while (g_count-- > 0)
	{
		cout << "===func1===";
		sleep(1);
	}
	cout << endl;
}

void my_func2_task()
{
	while (g_count-- > 0)
	{
		cout << "***func2***";
		sleep(1);
	}
	cout << endl;
}

int main(int argc, char *argv[])
{
	cout << "this is main()" << endl;
	thread thread_1(my_func1_task);
	thread thread_2(my_func2_task);
	
	thread_1.join();
	thread_2.join();
	return 0;
}

测试结果:
在这里插入图片描述
上锁测试示例:

int g_count = 10;
mutex g_countMtx;

void my_func1_task()
{
	g_countMtx.lock();
	while (g_count-- > 0)
	{
		cout << "===func1===";
		sleep(1);
	}
	cout << endl;
	g_countMtx.unlock();
}

void my_func2_task()
{
	g_countMtx.lock(); 
	while (g_count-- > 0)
	{
		cout << "***func2***";
		sleep(1);
	}
	cout << endl;
	g_countMtx.unlock();
}

int main(int argc, char *argv[])
{
	cout << "this is main()" << endl;
	thread thread_1(my_func1_task);
	thread thread_2(my_func2_task);
	
	thread_1.join();
	thread_2.join();
	return 0;
}

测试结果:
在这里插入图片描述

lock_guard

  • 作用:防止在lock后,忘记unlock。
  • 使用:在创建lock_guard对象时,将尝试获取提供给它的互斥锁的所有权。当控制流离开lock_guard对象的作用域时,lock_guard析构并释放互斥锁。
  • 特点:创建即加锁,作用域结束自动析构并解锁;不能中途解锁,必须等作用域结束才能解锁。
  • 使用技巧:可以根据需要通过使用{}增加临时作用域。
    测试示例:
int g_count = 10;
mutex g_countMtx;

void my_func1_task()
{
	lock_guard<mutex> guard(g_countMtx);
	while (g_count-- > 0)
	{
		cout << "===func1===";
		sleep(1);
	}
	cout << endl;
}

void my_func2_task()
{
	lock_guard<mutex> guard(g_countMtx); 
	while (g_count-- > 0)
	{	
		cout << "***func2***";
		sleep(1);
	}
	cout << endl;
}

int main(int argc, char *argv[])
{
	cout << "this is main()" << endl;
	thread thread_1(my_func1_task);
	thread thread_2(my_func2_task);
	
	thread_1.join();
	thread_2.join();
	return 0;
}

测试结果:
在这里插入图片描述

信号量 sem

C++下使用的信号量,实际上使用的也是C语言中的信号量,即使用库。

sem参数

  • 头文件
#include 
  • 类型
    sem_t
  • 函数接口
int sem_init(sem_t *sem, int pshared, unsigned int value);  // 创建信号量
int sem_post(sem_t *sem);    // 信号量的值加 1
int sem_wait(sem_t *sem);    // 信号量的值减 1
int sem_destroy(sem_t *sem); // 信号量销毁

示例

sem_t sem;

void func_1_task()
{
    cout << "start wait sem..." << endl;
    sem_wait(&sem);
    cout << "end wait sem..." << endl;
}

void func_2_task()
{
    sleep(5);
    cout << "I will post sem" << endl;
    sem_post(&sem);
}

int main()
{
    sem_init(&sem, 0, 0);

    thread th_1(func_1_task);
    th_1.detach();

    thread th_2(func_2_task);
    th_2.detach();

	while (1)
    {
        sleep(10);
    }
    sem_destroy(&sem);
    return 0;
}

测试结果
在这里插入图片描述

你可能感兴趣的:(C/C++,c++)