测试结果:
wq@wq-desktop:~/coding/muti_thread$ ./muti_thread_test_5hello in thread hello in thread hello in thread 410before sum is hello in thread 0 in thread 4after sum is 4 in thread 4hello in thread 23before sum is 4 in thread 1after sum is 5 in thread 1before sum is 5 in thread 0after sum is 5 in thread 0before sum is 5 in thread 2after sum is 7 in thread 2before sum is 7 in thread 3after sum is 10 in thread 3finally sum is 10可知,sum的访问和修改顺序是正常的,这就达到了多线程的目的了,但是线程的运行顺序是混乱的,混乱就是正常?
6.信号量的实现
信号量是线程同步的另一种实现机制,信号量的操作有signal和wait,本例子采用条件信号变量pthread_cond_t tasks_cond;
信号量的实现也要给予锁机制 。
#include <iostream>#include <pthread.h>#include <stdio.h> using namespace std; #define BOUNDARY 5 int tasks = 10;pthread_mutex_t tasks_mutex; //互斥锁pthread_cond_t tasks_cond; //条件信号变量,处理两个线程间的条件关系,当task>5,hello2处理,反之hello1处理,直到task减为0 void* say_hello2( void* args ){ pthread_t pid = pthread_self(); //获取当前线程id cout << "[" << pid << "] hello in thread " << *( ( int* )args ) << endl;bool is_signaled = false; //sign while(1) { pthread_mutex_lock( &tasks_mutex ); //加锁 if( tasks > BOUNDARY ) {cout << "[" << pid << "] take task: " << tasks << " in thread " << *( (int*)args ) << endl;--tasks; //modify } else if( !is_signaled ) {cout << "[" << pid << "] pthread_cond_signal in thread " << *( ( int* )args ) << endl;pthread_cond_signal( &tasks_cond ); //signal:向hello1发送信号,表明已经>5is_signaled = true; //表明信号已发送,退出此线程 } pthread_mutex_unlock( &tasks_mutex ); //解锁 if( tasks == 0 )break; } } void* say_hello1( void* args ){ pthread_t pid = pthread_self(); //获取当前线程id cout << "[" << pid << "] hello in thread " << *( ( int* )args ) << endl; while(1) { pthread_mutex_lock( &tasks_mutex ); //加锁 if( tasks > BOUNDARY ) {cout << "[" << pid << "] pthread_cond_signal in thread " << *( ( int* )args ) << endl;pthread_cond_wait( &tasks_cond, &tasks_mutex ); //wait:等待信号量生效,接收到信号,向hello2发出信号,跳出wait,执行后续} else {cout << "[" << pid << "] take task: " << tasks << " in thread " << *( (int*)args ) << endl; --tasks; } pthread_mutex_unlock( &tasks_mutex ); //解锁 if( tasks == 0 ) break; } }int main(){ pthread_attr_t attr; //线程属性结构体,创建线程时加入的参数 pthread_attr_init( &attr ); //初始化 pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE ); //是设置你想要指定线程属性参数,这个参数表明这个线程是可以join连接的,join功能表示主程序可以等线程结束后再去做某事,实现了主程序和线程同步功能 pthread_cond_init( &tasks_cond, NULL ); //初始化条件信号量 pthread_mutex_init( &tasks_mutex, NULL ); //初始化互斥量 pthread_t tid1, tid2; //保存两个线程id int index1 = 1; int ret = pthread_create( &tid1, &attr, say_hello1, ( void* )&index1 ); if( ret != 0 ) { cout << "pthread_create error:error_code=" << ret << endl; } int index2 = 2; ret = pthread_create( &tid2, &attr, say_hello2, ( void* )&index2 ); if( ret != 0 ) { cout << "pthread_create error:error_code=" << ret << endl; } pthread_join( tid1, NULL ); //连接两个线程 pthread_join( tid2, NULL );pthread_attr_destroy( &attr ); //释放内存pthread_mutex_destroy( &tasks_mutex ); //注销锁 pthread_cond_destroy( &tasks_cond ); //正常退出}测试结果:
先在线程2中执行say_hello2,再跳转到线程1中执行say_hello1,直到tasks减到0为止 。
wq@wq-desktop:~/coding/muti_thread$ ./muti_thread_test_6[3069823856] hello in thread 2[3078216560] hello in thread 1[3069823856] take task: 10 in thread 2 [3069823856] take task: 9 in thread 2[3069823856] take task: 8 in thread 2[3069823856] take task: 7 in thread 2[3069823856] take task: 6 in thread 2[3069823856] pthread_cond_signal in thread 2[3078216560] take task: 5 in thread 1[3078216560] take task: 4 in thread 1[3078216560] take task: 3 in thread 1[3078216560] take task: 2 in thread 1[3078216560] take task: 1 in thread 1
【c++多线程编程】
推荐阅读
- 三步了解JavaScript的组成
- C++友元函数和友元类用法详解
- 多网关配置 Windows命令:route命令使用实例详解
- pointer-like class C++|封装裸指针为像指针的类
- C++list的使用总结及常用list操作
- 骚白王者荣耀吉尼斯世界纪录回放 骚白王者荣耀吉尼斯世界纪录多少星
- 肚子减肥的运动有什么?
- 淘宝如何满足一证多店 淘宝一证多店需要什么条件
- 做运动怎么减肥呢?
- 简单的减肥运动方法有什么?
