c++基础线程篇

目录

C++11线程

POSIX线程

 线程属性

调度策略与优先级

 线程同步 

互斥锁  

条件变量  


C++11线程

#include <thread>

void task(int i) {
	cout << "task:" << i << endl;
}

thread t1(task,100);
//等待线程结束再继续执行
t1.join();

POSIX线程

POSIX 是可移植操作系统接口,标准定义了操作系统应该为应用程序提供的接口标准 。

当然了,Windows也是实现了该接口,我们可以下载一个动态库到你的开发环境里使用这些接口,下载地址:ftp://sourceware.org/pub/pthreads-win32/pthreads-w32-2-9-1-release.zip,解压之后,里面就有我们需要用到pthreadVC2.dll动态库文件。下面在编写线程的程序

#include <pthread.h>
void *pthreadTask(void* args) {
	int* i = static_cast<int*>(args);
	cout << "posix线程:" << *i << endl;
	return 0;
}
pthread_t pid;
int pi = 100;
pthread_create(&pid, 0, pthreadTask, &pi);
//等待线程的结束
pthread_join(pid,0);

 线程属性

线程创建默认是非分离的,当pthread_join()函数返回时,创建的线程终止,释放自己占用的系统资源。分离线程不能被其他线程等待,pthread_join无效,线程自己玩自己的。

//设置是否为分离线程
//PTHREAD_CREATE_DETACHED 分离
//PTHREAD_CREATE_JOINABLE 非分离
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);

调度策略与优先级

Windows 无法设置成功。

//设置调度策略 
//返回0 设置成功
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
// SCHED_FIFO 
//	实时调度策略,先到先服务 一旦占用cpu则一直运行。一直运行直到有更高优先级任务到达或自己放弃。
// SCHED_RR
//	实时调度策略,时间轮转 系统分配一个时间段,在时间段内执行本线程


//设置优先级
//获得对应策略的最小、最大优先级
int max = sched_get_priority_max(SCHED_FIFO);
int min = sched_get_priority_min(SCHED_FIFO);
sched_param param;
param.sched_priority = max;
pthread_attr_setschedparam(&attr, &param);

 线程同步 

多线程同时读写同一份共享资源的时候,可能会引起冲突。需要引入线程“同步”机制,即各位线程之间有序地对共享资源进行操作。

#include <pthread.h>
using namespace std;

queue<int> q;
void *pop(void* args) {
    //线程未同步导致的多线程安全问题
    // 会有重复的数据取出并出现异常
	if (!q.empty())
	{
		printf("取出数据:%d\n", q.front());
		q.pop();
	}
	else {
		printf("无数据\n");
	}
	return 0;
}

int main()
{
	for (size_t i = 0; i < 5; i++)
	{
		q.push(i);
	}
	pthread_t pid[10];
	for (size_t i = 0; i < 10; i++)
	{
		pthread_create(&pid[i], 0, pop, &q);
	}
	system("pause");
	return 0;
}

互斥锁  

queue<int> q;
pthread_mutex_t mutex;
void *pop(void* args) {
	// 锁
	pthread_mutex_lock(&mutex);
	if (!q.empty())
	{
		printf("取出数据:%d\n", q.front());
		q.pop();
	}
	else {
		printf("无数据\n");
	}
    // 放
	pthread_mutex_unlock(&mutex);
	return 0;
}

int main()
{
    //初始化互斥锁
	pthread_mutex_init(&mutex, 0);
	for (size_t i = 0; i < 5; i++)
	{
		q.push(i);
	}
	pthread_t pid[10];
	for (size_t i = 0; i < 10; i++)
	{
		pthread_create(&pid[i], 0, pop, &q);
	}
    //需要释放
 	for (size_t i = 0; i < 10; i++)
	{
		pthread_join(pid[i], 0);
	}
	pthread_mutex_destroy(&mutex);
	system("pause");
	return 0;
}

条件变量  

条件变量是线程间进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立",从而唤醒挂起线程 。

template <class T>
class SafeQueue {
public:
	SafeQueue() {
		pthread_mutex_init(&mutex,0);
	}
	~SafeQueue() {
		pthread_mutex_destory(&mutex);
	}
	void enqueue(T t) {
		pthread_mutex_lock(&mutex);
		q.push(t);
		pthread_mutex_unlock(&mutex);
	}
	int dequeue(T& t) {
		pthread_mutex_lock(&mutex);
		if (!q.empty())
		{
			t = q.front();
			q.pop();
			pthread_mutex_unlock(&mutex);
			return 1;
		}
		pthread_mutex_unlock(&mutex);
		return 0;
	}

private:
	queue<T> q;
	pthread_mutex_t mutex;
};

上面的模板类存放数据T,并使用互斥锁保证对queue的操作是线程安全的。这就是一个生产/消费模式。如果在取出数据的时候,queue为空,则一直等待,直到下一次enqueue加入数据。这就是一个典型的生产/消费模式, 加入条件变量使 “dequeue” 挂起,直到由其他地方唤醒。

#pragma once
#include <queue>
using namespace std;

template <class T>
class SafeQueue {
public:
	SafeQueue() {
		pthread_mutex_init(&mutex,0);
		pthread_cond_init(&cond, 0);
	}
	~SafeQueue() {
		pthread_mutex_destory(&mutex);
		pthread_cond_destory(&cond);
	}
	void enqueue(T t) {
		pthread_mutex_lock(&mutex);
		q.push(t);
		//发出信号 通知挂起线程
		//由系统唤醒一个线程
		//pthread_cond_signal(&cond);
		// 广播 对应多个消费者的时候 多个线程等待唤醒所有
		pthread_cond_broadcast(&cond);
		pthread_mutex_unlock(&mutex);
	}
	int dequeue(T& t) {
		pthread_mutex_lock(&mutex);
		//可能被意外唤醒 所以while循环
		while (q.empty())
		{
			pthread_cond_wait(&cond, &mutex);
		}
		t = q.front();
		q.pop();
		pthread_mutex_unlock(&mutex);
		return 1;
	}

private:
	queue<T> q;
	pthread_mutex_t mutex;
	pthread_cond_t cond;
};
#include "lsn6_example.h"
#include <thread>
#include <pthread.h>

using namespace std;
#include "safe_queue.h"

SafeQueue<int> q;

void *get(void* args) {
	while (1) {
		int i;
		q.dequeue(i);
		cout << "消费:"<< i << endl;
	}
	return 0;
}
void *put(void* args) {
	while (1)
	{
		int i;
		cin >> i;
		q.enqueue(i);
	}
	return 0;
}
int main()
{
	pthread_t pid1, pid2;
	pthread_create(&pid1, 0, get, &q);
	pthread_create(&pid2, 0, put, &q);
	pthread_join(pid2,0);
	system("pause");
	return 0;
}

线程先学到这里。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值