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

前端之家收集整理的这篇文章主要介绍了多线程 – 在pthread中,如何可靠地将信号传递给另一个线程?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图在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);

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

原文链接:https://www.f2er.com/java/123839.html

猜你在找的Java相关文章