C++ c+中的螺纹+;Linux无限期等待

C++ c+中的螺纹+;Linux无限期等待,c++,linux,multithreading,C++,Linux,Multithreading,我们必须编写程序来创建两个线程。第一个线程将从键盘请求字母,然后它将向正在等待它的第二个线程发送信号。然后它将把这个字母改为大写字母,如果这个字母不是“E”,它将向线程1发送另一个信号。什么会使线程再次运行,直到您键入的字母不是“e” 两个线程之间的通信有点类似于打乒乓球,或者至少应该是这样 下面我添加了我写的一段代码。它还没有完成,但有一个问题我无法修复或找到解决方案。当我试图运行这段代码时,它被卡住了。看起来两个线程都在等待信号,所以什么都没有发生 怎么了 #include <iost

我们必须编写程序来创建两个线程。第一个线程将从键盘请求字母,然后它将向正在等待它的第二个线程发送信号。然后它将把这个字母改为大写字母,如果这个字母不是“E”,它将向线程1发送另一个信号。什么会使线程再次运行,直到您键入的字母不是“e”

两个线程之间的通信有点类似于打乒乓球,或者至少应该是这样

下面我添加了我写的一段代码。它还没有完成,但有一个问题我无法修复或找到解决方案。当我试图运行这段代码时,它被卡住了。看起来两个线程都在等待信号,所以什么都没有发生

怎么了

#include <iostream>
#include <fstream>
#include <string>
#include <pthread.h>
#include <stdlib.h>

using namespace std;

pthread_mutex_t mut;
pthread_cond_t dadam;
pthread_cond_t dudum;

char x;

void *first(void *arg) {
  while(1) {  
    pthread_mutex_lock(&mut);
    pthread_cond_wait(&dadam, &mut);
    cout << "Type a letter\n";
    cin >> x; 
    pthread_mutex_unlock(&mut);
    pthread_cond_signal(&dudum);
  }
}

void *second(void *arg) { 
  while(1) {
    pthread_cond_wait(&dudum, &mut); 
    pthread_mutex_lock(&mut);
    char y;
    y = toupper(x);
    cout << y << endl;
    pthread_mutex_unlock(&mut);
    pthread_cond_signal(&dadam);
  }
}

int main()
{
  pthread_t nun;
  pthread_t nuno;

  pthread_create(&nun, NULL, &first,NULL);
  pthread_create(&nuno, NULL, &second,NULL);
  pthread_cond_signal(&dadam);
  pthread_join(nun, NULL);
  pthread_join(nuno, NULL);

  return 0;
}
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
pthread_mutex_t mut;
pthread_cond_t dadaam;
pthread_cond_t dududum;
字符x;
void*first(void*arg){
而第(1)款{
pthread_mutex_lock(&mut);
pthread_cond_wait(&dadam,&mut);
cout>x;
pthread_mutex_unlock(&mut);
pthread_cond_信号(&dudum);
}
}
空*秒(空*arg){
而(1){
pthread_cond_wait(&dudum,&mut);
pthread_mutex_lock(&mut);
chary;
y=toupper(x);

不能初始化互斥体或条件变量。它们具有静态持续时间,因此参与默认初始化,但不能保证这会产生可用状态。实现这一点的通用方法是使用
pthread\u cond\u init()
pthread\u mutex\u init()
,但如果默认值足够,则也可以使用初始化器宏:

pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t dadam = PTHREAD_COND_INITIALIZER;
pthread_cond_t dudum = PTHREAD_COND_INITIALIZER;
您还尝试在CV
dudum
上等待,但不保留指定的互斥体。在调用
pthread\u cond\u wait()
时,您需要保留互斥体:

(并非相反)

但主要问题似乎是实现中的竞争条件

在循环的每次迭代中,函数
first()
在继续之前等待CV
dadaam
,在循环的每次迭代中,函数
second()
在继续之前等待CV
dududum
。如果可以将其引导,这可能会起作用,但当您第一次启动这两个函数时,两个函数都不能通过等待来向另一个正在等待的CV发送信号。您可以从主线程发送信号
dadaam
,但如果主线程在
fi之前发送信号rst()
开始等待,然后信号将丢失

不足: 建议:

  • 正确初始化互斥体和CV
  • 修复函数
    second()
    中的互斥作用域问题;以及
  • main()
    中,在互斥锁的保护下执行线程创建(而不是连接);以及
  • 在函数
    first()
  • main()
    中删除
    pthread\u cond\u signal()
    ,因为不再需要它。

  • 请注意,在锁定目标CV的关联互斥锁的同时执行
    pthread\u cond\u signal()
    是安全的。不需要这样做,但一些人建议这样做是一种良好的做法。

    您应该初始化互斥锁变量

    除此之外,第一个线程似乎将等待事件
    dadaam

    确保事件是为线程<代码> > 生成的。

    C和C++是不同的语言,有不同的方法。<代码>使用命名空间STD<代码>。这只是C代码。C++必须处理这个问题。在调用<代码> pthRead CONDIGHORION>代码>之前,必须检查您要等待的东西是否已经发生。在继续执行代码> pthRead SCODLDIONE/<代码>返回之前,必须检查以确保您要等待的对象为ALRE。ady发生了。条件变量是无状态的,不知道您在等待什么。您有100%的责任确保在需要时调用
    pthread\u cond\u wait
    。模式是
    pthread\u mutex\u lock(…);而(有些事情尚未发生)pthread\u cond\u wait(…)…东西..pthread\u mutex\u unlock(…)我用C在C++之前尝试过,但是在尝试过许多不想要的片段之后,老实说,我把我想做的和类型混合起来。不管怎样,抱歉,我想说一下David Schwartz对你的问题的评论,他说得很对。我的建议不足以让你的代码按照他所说的那样做。因此,这是不够的。要解决这个问题。上面列出的大多数问题都是在我试图自己解决它时产生的。最有趣的是,我试图用老师给我们帮助的代码来解决它。遗憾的是,这一点都没有帮助。如果出于好奇,我可以问我应该如何做第3点?我已经解决了,而且它很有效,但我没有我很好奇。无论如何,非常感谢你们两位的帮助。@LukeS,你可以(3)在第一个
    pthread\u create()之前锁定互斥锁(
    pthread\u mutex\u lock()
    ,并在第二次之后解锁。@Josh Bollinger真的,非常感谢你。感谢你的解释,我修复了它,了解了代码和我的想法的问题所在;)真的感谢你,并为愚蠢的问题感到抱歉。再次非常感谢,祝你度过愉快的一天
    pthread_mutex_lock(&mut);
    pthread_cond_wait(&dudum, &mut);