加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

多线程 – 在pthread中,如何可靠地将信号传递给另一个线程?

发布时间:2020-12-14 17:47:49 所属栏目:Java 来源:网络整理
导读:我试图在pthread中编写一个简单的线程池程序.但是,似乎pthread_cond_signal不会阻塞,这会造成问题.例如,假设我有一个“生产者 – 消费者”程序: pthread_cond_t my_cond = PTHREAD_COND_INITIALIZER;pthread_mutex_t my_cond_m = PTHREAD_MUTEX_INITIALIZER
我试图在pthread中编写一个简单的线程池程序.但是,似乎pthread_cond_signal不会阻塞,这会造成问题.例如,假设我有一个“生产者 – 消费者”程序:
pthread_cond_t my_cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t my_cond_m = PTHREAD_MUTEX_INITIALIZER;

void * liberator(void * arg)
{
    // XXX make sure he is ready to be freed
    sleep(1);

    pthread_mutex_lock(&my_cond_m);
    pthread_cond_signal(&my_cond);
    pthread_mutex_unlock(&my_cond_m);

    return NULL;
}

int main()
{
    pthread_t t1;
    pthread_create(&t1,NULL,liberator,NULL);

    // XXX Don't take too long to get ready. Otherwise I'll miss 
    // the wake up call forever
    //sleep(3);

    pthread_mutex_lock(&my_cond_m);
    pthread_cond_wait(&my_cond,&my_cond_m);
    pthread_mutex_unlock(&my_cond_m);

    pthread_join(t1,NULL);

    return 0;
}

如两个XXX标记中所述,如果我拿走了睡眠呼叫,那么main()可能会因为已经从liberator()中忽略了唤醒呼叫而失效.当然,睡眠不是一个非常强大的方式来确保.

在现实生活中,这将是一个工作线程,告诉管理员线程,它已准备好工作,或者管理员线程宣布新的工作可用.

你如何在pthread中可靠地执行此操作?

@ Borealid的回答的作品,但他对这个问题的解释可能会更好.我建议任何人看这个问题来阅读评论中的讨论,以了解发生了什么.

特别是,我自己会修改他的答案和代码示例,使之更清晰. (自从Borealid的原始答案,编译和工作,困惑了我很多)

// In main
pthread_mutex_lock(&my_cond_m);

// If the flag is not set,it means liberator has not 
// been run yet. I'll wait for him through pthread's signaling 
// mechanism

// If it _is_ set,it means liberator has been run. I'll simply 
// skip waiting since I've already synchronized. I don't need to 
// use pthread's signaling mechanism
if(!flag) pthread_cond_wait(&my_cond,&my_cond_m);

pthread_mutex_unlock(&my_cond_m);

// In liberator thread
pthread_mutex_lock(&my_cond_m);

// Signal anyone who's sleeping. If no one is sleeping yet,// they should check this flag which indicates I have already 
// sent the signal. This is needed because pthread's signals 
// is not like a message queue -- a sent signal is lost if 
// nobody's waiting for a condition when it's sent.
// You can think of this flag as a "persistent" signal
flag = 1;
pthread_cond_signal(&my_cond);
pthread_mutex_unlock(&my_cond_m);

解决方法

使用同步变量.

主要内容:

pthread_mutex_lock(&my_cond_m);
while (!flag) {
    pthread_cond_wait(&my_cond,&my_cond_m);
}
pthread_mutex_unlock(&my_cond_m);

在线程中:

pthread_mutex_lock(&my_cond_m);
flag = 1;
pthread_cond_broadcast(&my_cond);
pthread_mutex_unlock(&my_cond_m);

对于生产者 – 消费者问题,这将是消费者在缓冲区为空时休眠,并且生产者在充满时休眠.记住在访问全局变量之前获取锁.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读