C++多线程编程信号量
用信号量实现的线程安全队列。
#include "stdafx.h"
#include <iostream>
#include <pthread.h>
//多线程头文件,可移植众多平台, pthread头文件和库需要自己下载,
//下载地址 https://sourceware.org/pthreads-win32/#download
//进入下载网站找到相应的 .exe下载即可,各种版本均可
#define BOUNDARY 5 //定义边界
int tasks = 10; //任务量
pthread_mutex_t tasks_mutex; //互斥锁
//条件信号变量,处理两个线程间的条件关系,当task > 5, hello2 处理,
//直到 task 减为 0
pthread_cond_t tasks_cond;
using namespace std;
//信号量的实现
//信号量是线程同步的另一种实现机制,信号量的操作有 signal和 wait,
//本例采用条件信号量pthread_cond_t
//信号量的实现也要给予锁机制
class hhh
{
public:
//如何在线程函数中传入参数
static void * sayHello2( void * args)
{
//获取当前线程 id
pthread_t pid = pthread_self();
std::cout<<"[ "<< "pid" <<"] hello in thread "<<*((int *)args)<<endl;
bool is_signaled = false; //sign
while (true)
{
pthread_mutex_lock(&tasks_mutex);//加锁
if (tasks > BOUNDARY)
{
std::cout<<"[" << "pid" << "] take task: " << tasks<<" in thread "<<*((int *)args)<<endl;
--tasks; //modify
}
else if ( !is_signaled)
{
std::cout<<"[" << "pid" <<"] pthread_cond_signal in thread "<<*((int *)args)<<endl;
pthread_cond_signal(&tasks_cond); //signal:向hello1发送信号,表明已经 > 5
is_signaled = true; //表明信号已发送,退出此线程
}
//解锁
pthread_mutex_unlock(&tasks_mutex);
if (tasks == 0)
{
break;
}
}
return NULL;
}
static void * say_hello1(void * args)
{
//获取当前线程id
pthread_t pid = pthread_self();
std::cout<<"["<<"pid"<<"] hello in thread "<< *((int *)args) <<endl;
while (true)
{
//加锁
pthread_mutex_lock(&tasks_mutex);
if (tasks > BOUNDARY)
{
std::cout<<"[" <<"pid"<<"] pthread_cond_signal in thread"<< *((int *)args) <<endl;
//wait:等待信号量失效,接收到信号,向hello2发出信号,跳出wait,执行后续
pthread_cond_wait(&tasks_cond, &tasks_mutex);
}else
{
std::cout<<"["<<"pid"<<"] take task : " <<tasks << "in thread"<< *((int *)args) <<endl;
--tasks;
}
pthread_mutex_unlock(&tasks_mutex);
if (tasks == 0)
{
break;
}
}
//解锁
return NULL;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
//线程属性结构体,创建线程时加入的参数
pthread_attr_t attr;
//初始化
pthread_attr_init(&attr);
//设置想要指定线程属性参数,这个参数表明这个线程是jion连接的,join功能表示主线程可以等线程
//结束后再去做某事,实现了主程序和线程同步功能
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
//初始化条件信号量
pthread_cond_init(&tasks_cond, NULL);
//初始化互斥量
pthread_mutex_init(&tasks_mutex, NULL);
//保存两个线程id
pthread_t tid1, tid2;
int index1 = 1;
int ret = pthread_create(&tid1, &attr, hhh::say_hello1, (void *)&index1);
if (ret != 0)
{
std::cout<<"pthread_create error "<<ret<<endl;
}
int index2 = 2;
ret = pthread_create(&tid2, &attr, hhh::sayHello2, (void *)&index2);
if (ret != 0)
{
std::cout<<"pthread_create error "<< ret <<endl;
}
//连接两个线程
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
//释放内存
pthread_attr_destroy(&attr);
//注销锁
pthread_mutex_destroy(&tasks_mutex);
//退出
pthread_cond_destroy(&tasks_cond);
return 0;
}
运行如下
再次运行
//测试结果:
//先在线程2中执行say_hello2,再跳转到线程1中执行say_hello1,知道tasks减到0为止