Linux 信号量的实现

发布于 2024-11-03 18:13:20 字数 4759 浏览 5 评论 0

信号量是线程同步的另一种实现机制,信号量的操作有 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 发送信号,表明已经>5
is_signaled = true; //表明信号已发送,退出此线程
}
pthread_mutex_unlock( &tasks_mutex ); //解锁
if( tasks == 0 )
break;
}
return NULL;
}

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;
}
return NULL;
}


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 ); //正常退出
return 0;
}

测试结果:

先在线程 2 中执行 say_hello2,再跳转到线程 1 中执行 say_hello1,直到 tasks 减到 0 为止。

jack@jack:~/coding/muti_thread$ ./pthread_chap6  
[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

到此,对多线程编程有了一个初步的了解,当然还有其他实现线程同步的机制,有待进一步探索。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

柠檬心

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

lee_heart

文章 0 评论 0

往事如风

文章 0 评论 0

春风十里

文章 0 评论 0

纸短情长

文章 0 评论 0

qq_pdEUFz

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文