我有三个线程-线程1打印“良好”,线程2打印“早晨”,线程3打印“全部”。如何使用这些线程在屏幕上连续打印“ Good Morning All”?
答案 0 :(得分:0)
对于一个,您只是在浪费资源。
但是,假设您确实需要此功能来完成比仅打印单词更重要的事情,这是一个建议:
创建3个互斥锁(pthread_mutex)
pthread_mutex_t m_Good, m_Morning, m_all;
pthread_mutex_init(&m_Good, NULL);
pthread_mutex_init(&m_Morning, NULL);
pthread_mutex_init(&m_All, NULL);
锁定最后两个互斥锁
pthread_mutex_lock(&m_Morning);
pthread_mutex_lock(&m_All);
在第一个线程中打印其消息,然后解锁第二个互斥锁。
while(true){
if(pthread_mutex_lock(&m_Good)==0){
printf("GOOD ");
pthread_mutex_unlock(&m_Morning);
pthread_mutex_lock(&m_Good);
}
}
答案 1 :(得分:0)
这是一个简单的无锁实现,用于强制顺序执行线程。它使用一个原子状态变量,可以表示四个可能的状态:
working
=其中一个线程正在工作ready_for_task1
=轮到task1开始工作了ready_for_task2
=轮到task2开始工作了ready_for_task3
=轮到task3开始工作了通常的想法是循环遍历这些状态:
ready_for_task1 ->
working ->
ready_for_task2 ->
working ->
ready_for_task3 ->
working ->
ready_for_task1 ->
...
第一部分,定义状态,声明全局原子状态,并定义执行状态转换的保护类。通过自动检查其就绪状态并将状态切换为工作状态,后卫的后卫构造函数将“忙于”等待。 Guard析构函数会将状态设置为下一个任务的就绪状态。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <atomic>
enum State { ready_for_task1, ready_for_task2, ready_for_task3, working };
static std::atomic< State > state_;
class TransitionGuard {
public:
TransitionGuard(State start, State finish) : finish_(finish) {
State expecting = start;
while( !state_.compare_exchange_weak( expecting, working ) ) {
expecting = start;
asm("pause");
}
}
~TransitionGuard() {
state_.store( finish_ );
}
private:
const State finish_;
};
然后每个线程运行自己的循环,在各自的过渡保护下打印其单词。
void * task1( void * data )
{
while( true ) {
TransitionGuard guard( ready_for_task1, ready_for_task2 );
printf( "Good" );
}
}
void * task2( void * data)
{
while( true ) {
TransitionGuard guard( ready_for_task2, ready_for_task3 );
printf( " Morning" );
}
return NULL;
}
void * task3( void * data)
{
while( true ) {
TransitionGuard guard( ready_for_task3, ready_for_task1 );
printf( " All\n" );
}
return NULL;
}
最后,您需要在创建线程之前初始化状态。
int main( int argc, const char ** argv )
{
state_ = ready_for_task1;
pthread_t thread1, thread2, thread3;
if( pthread_create( &thread1, NULL, task1, NULL ) )
{
fprintf( stderr, "thread1 failed to start\n" );
exit(EXIT_FAILURE);
}
if( pthread_create( &thread2, NULL, task2, NULL ) )
{
fprintf( stderr, "thread2 failed to start\n" );
exit(EXIT_FAILURE);
}
if( pthread_create( &thread3, NULL, task3, NULL ) )
{
fprintf( stderr, "thread3 failed to start\n" );
exit(EXIT_FAILURE);
}
pthread_join( thread1, NULL );
pthread_join( thread2, NULL );
pthread_join( thread3, NULL );
fprintf( stderr, "threads joined. exiting.\n" );
exit(EXIT_SUCCESS);
}