POSIX多线程编程(一)

POSIX多线程编程(一)

一、线程创建、启动

线程标识

每个进程拥有一个进程ID标识,线程对应的标识是线程ID和进程ID不同的是,进程ID在整个系统唯一,而线程ID只在所需进程中才有意义。线程ID使用phtread_t结构表示,因此不能把它当整数处理。在比较线程时,通过函数:

#include 
// 相同时返回非0,否则返回0
int pthread_equal(pthread_t tid1, pthread_t tid2);

// 获取线程自身ID
pthread_t pthread_self(void);

线程启动

传统UNIX进程中,每个进程有一个控制线程,可以认为正常程序启动后,任务在主线程中完成。可以通过pthread_create 新增线程,新增成功后返回0,否则返回错误码。线程启动后,便无法确定调用线程和新建线程的执行顺序了,因此创建后,要处理好调用线程和新建线程的竞争。

#include 
#include 
#include 

void* thr_test(void* arg)
{
    printf("hello!\n");
    return 0;
}

int main(int argc, char* argv[])
{
    pthread_t thid;
    int err = pthread_create(&thid, NULL, thr_test, NULL);
    if (err != 0)
    {
        printf("can't create thread!\n");
    }
    sleep(1);   // 防止主线程直接退出,新线程还未执行
    return 0;
}

C++编程多为面向对象的编程方式,很多时候启动线程在类中实现,当启动函数为类方法时,普通成员函数作为pthread_create的线程启动函数会出现参数问题,因为当把线程启动函数封装在类中时,this指针会作为默认参数传入到函数中,与线程启动函数的void*不能匹配。因此,要把线程启动函数声明为静态方法。

#include 
#include 
#include 

class ThreadTest
{
public:
    static void* run(void* arg)
    {
        printf("hello!\n");
        return 0;
    }
    void start()
    {
        pthread_create(&m_thid, NULL, run, NULL);
    }
    int m_num;
    pthread_t m_thid;
};

int main(int argc, char* argv[])
{
    ThreadTest test;
    test.start();
    sleep(1);
    return 0;
}

如上,便完成了通过成员函数启动。但是在类中,静态成员函数无法访问非静态成员变量和方法。这样,通过静态成员函数启动无法操作类成员,解决该问题,可以将this指针作为参数传递。

#include 
#include 
#include 
// 线程创建函数仅支持void*一个参数,因为为传递多个参数,需要自定义结构

class ThreadTest
{
public:
    static void* run(void* arg)
    {
        ThreadTest* pThis = (ThreadTest*)arg;
        printf("hello, the number is %d!\n",pThis->m_num);
        return 0;
    }
    void start()
    {
        pthread_create(&m_thid, NULL, run, (void*)this);
    }
    int m_num;
    pthread_t m_thid;
};

int main(int argc, char* argv[])
{
    ThreadTest test;
    test.start();
    sleep(1);
    return 0;
}

ps:线程可以接受的启动函数中仅能传递一个参数,因此,想传递多个参数时,需要自己定义参数结构传输。

你可能感兴趣的:(linux开发,多线程,POSIX)