困在pthread_create和静态函数之间 - 我该如何前进?

时间:2015-08-12 00:09:57

标签: c++ pthreads

我正在用C ++编写一个简单的媒体播放器程序,我试图让它成为多线程的。我想要" MediaPlayer"对象在启动后立即在其自己的线程中运行(如下面的main.cpp所示)。但是,如果用户通过输入" PP"来决定播放播放列表。在控制台中我希望媒体播放器产生另一个播放播放列表中所有歌曲的线程。但这样做需要我制作功能" ThreadPlay"静止的。但制作" ThreadPlay" static会给我带来麻烦,因为它不会让我调用MediaPlayer :: play()!

我该如何解决这个问题?

的main.cpp

void * ThreadMediaPlayer(void *threadid)
{
    long tid;
    tid = (long)threadid;
    printf("Hello World! It's me, thread #%ld!\n", tid);

    MediaPlayer myPlayer;
    myPlayer.start();

    return NULL;

}

int main(int argc, const char * argv[])
{
    pthread_t playerThread;
    int rc1 = pthread_create(&playerThread, NULL, ThreadMediaPlayer, (void *)0);
    pthread_exit(NULL);
    return 0;
}

MediaPlayer.h

struct UserData {
    long threadId;
    string playlistName;
};

MediaPlayer.cpp

void MediaPlayer::start(){
    // get commands

    while (true){
        string command;

        cout << "(CS) Create Song <song name> <length in seconds>" << endl;
        cout << "(CP) Create Playlist <playlist name> " << endl;
        cout << "(A)  Add songs to playlist <playlist name> <song name>" << endl;
        cout << "(PP) Play Playlist <Playlist name> " << endl;
        cout << "(Q)uit" << endl;

        cin >> command;

        if (command == "Q"){
            break;
        }
        parseAndProcessCommand(command);

    }
}


 static void * ThreadPlay(void * userData)
{
    long tid;
    tid = ((struct UserData *)userData)->threadId;
    string playlistName = ((struct UserData *)userData)->playlistName;
    printf("Hello World! It's me, thread #%ld!\n", tid);

    play( playlistName    );

    return NULL;
}

3 个答案:

答案 0 :(得分:0)

您将this作为pthread_create的最后一个参数传递,然后您的静态函数将void *强制转换为您的类类型并调用非静态方法。

答案 1 :(得分:0)

理想情况下,您只需使用std::thread,因为它具有合适的构造函数并且易于使用。假设你没有使用它,因为你没有C ++ 11,你会发现实际上还有另一个问题,你甚至没有注意到:pthread_create()需要一个extern "C"功能。方便的是,它还将用户数据指针作为参数:您将该点用于您的对象。

也就是说,你的线程入口函数看起来像这样:

extern "C"
void* entry(void* data) {
     static_cast<MediaPlayer*>(data)->start();
     return 0;
}

...而且你打电话给pthread_create()这样的事情:

MediaPlayer player(/* probably some ctor arguments */);
pthread_create(&playerThread, 0, entry, &player);

答案 2 :(得分:0)

您可以将MediaPlayer的对象指针包含到UserData中,并创建一个非静态版本的ThreadPlay。在现有的静态ThreadPlay中,使用UserData中的MediaPlayer对象指针来调用ThreadPlay的非静态版本。