Я полагаю, вы, возможно, неправильно поняли некоторые концепции потоков. Звучит так, как будто вы хотите запустить два потока, а затем из одного контекста потока вызвать функцию в другой контекст потока, а это не то, как работают потоки.
Когда вы запускаете эти два потока, они выполняются независимо друг от друга. Они могут делиться доступом к данным, но вы не можете переплетать их выполнение так, как вам этого хочется. Если вы хотите, чтобы один поток выполнял что-то по запросу другого, у вас есть два решения для двух вещей:
- Какой механизм использовать для передачи запроса от одного потока к другому
- Должен ли запрашивающий поток остановиться и подождать "квитанцию" или просто счастливо продолжить, пока другой поток делает то, что ему было предложено.
A очень простой (и не совсем безопасный, просто иллюстрирующий логику) механизм, позволяющий сделать это, используя два bools для сигнализации о запросе, например:
Thread one starts | Thread two starts
Thread one works | Thread two loops checking a `bool DoSomething;`
Thread one sets bool DoSomething |
Thread one loops waiting for DidSomething | Thread two beeps
| Thread two sets DidSomething
Thread one continues working |
Следует отметить, что между контекстами потоков нет "вызовов". Два потока выполняются одновременно и обмениваются данными, используя данные (два объекта bools).
В реальной многопоточности вам нужно беспокоиться об одновременном доступе к данным. Что бы, например, произойдет, если два потока одновременно на двухъядерном компьютере попытались добавить данные в один и тот же список. Оба потока могут видеть один и тот же «указатель конца списка», оба будут создавать новую запись, оба обновят «указатель конца списка». Но одно из изменений перезапишет другое, и в лучшем случае у вас будут некоторые потерянные данные и утечка памяти, а в худшем - сбой.
Здесь вы используете механизм «взаимного исключения»: каждый поток, прежде чем получить доступ к такому общему ресурсу, как список, получит мьютекс. Мьютекс сконструирован таким образом, что его может «владеть» только один поток за раз. Если первый поток получит мьютекс первым, он продолжит обновление списка, а затем отпустит мьютекс. В то же время, другие потоки, пытающиеся получить мьютекс, будут просто сидеть, вызов Mutex :: acqu () не будет возвращаться, пока один поток не будет завершен с мьютексом. Если оба потока ведут себя хорошо и получают мьютекс перед доступом к общему списку, описанного выше одновременного обновления не произойдет, и список будет полностью действительным после того, как оба потока обновили его.
В ответ на комментарии:
Вы не можете запустить два потока одновременно. Ближайшим приближением было бы создание и запуск Two из One :: run:
void One::run()
{
Two b;
b.start();
cout<<"One run\n";
int i=0;
for(;;)
{
i++;
cout<<"+++ "<<i<<endl;
if(i==10)
break;
sleep(3);
}
b.wait();
}