POSIX多线程编程(一)

本文介绍POSIX多线程编程中线程的创建与启动过程,包括线程ID的概念及其比较方法,如何使用pthread_create函数创建新线程,并探讨了在C++类中实现线程启动的方法。

POSIX多线程编程(一)

一、线程创建、启动

线程标识

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

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

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

线程启动

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

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>

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 <pthread.h>
#include <unistd.h>
#include <stdio.h>

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 <pthread.h>
#include <unistd.h>
#include <stdio.h>
// 线程创建函数仅支持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:线程可以接受的启动函数中仅能传递一个参数,因此,想传递多个参数时,需要自己定义参数结构传输。

Today, there are three primary sets of multithreading (MT) libraries: the“standards-based” libraries (all of the UNIX® implementations and VMS, whichare moving to POSIX), the OS/2® library, and the Win32 library. (The NT andOS/2 libraries are fairly similar, which should not be too surprising. NT did startlife as OS/2, version 2, after all.) Although the APIs1 and implementations differsignificantly, the fundamental concepts are the same. The ideas in this book arevalid for all three; the details of the APIs differ.All the specific discussion in this book focuses on the POSIX multithreadingmodel, with comparisons to OS/2 and Win32 throughout.A frank note about our motivation is in order here. We have slaved away forcountless hours on this book because we’re propeller-heads who honestly believethat this technology is a superb thing and that the widespread use of it will makethe world a better place for hackers like ourselves.Your motivations for writing MT programs? You can write your programs betterand more easily, they’ll run faster, and you’ll get them to market more quickly,they’ll have fewer bugs, you’ll have happier programmers, customers, and highersales. The only losers in this game are the competitors, who will lag behind youin application speed and quality.MT is here today. It will soon be ubiquitous. As a professional programmer, youhave an obligation to understand this technology. It may or may not beappropriate for your current project, but you must be able to make thatconclusion yourself. This book will give you what you need to make thatdecision.Welcome to the world of the future!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值