关于多线程以及其访问类的成员函数

本文介绍了如何在C/C++中使用多线程和指针函数来传递参数,并通过实例展示了如何访问类成员函数。文章包括了多线程创建、线程间通信以及指针函数在类成员访问中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一般的多线程传递参数的程序

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

//gcc -lpthread -o cpro cpro.c

void *test(void *p)
{
	int *a = (int *)p;
	printf("num = %d\n",*a);
}
int main()
{
	int a = 5;

	int *p = &a;

	pthread_t id;

	pthread_create(&id,NULL,(void*)test, p);

	pthread_join(id,NULL);

	return 0;
}

二 使用指针函数访问类的成员函数

#include <stdio.h>
#include <pthread.h>
#include <iostream>
//g++ -lpthread -o cpro cpro.cpp
class triangle
{
	private:
		int length;
		int width;
		int height;

	public:
		triangle();
		virtual ~triangle();
		static void displayFirst(triangle *pthis);
		void display();
};

triangle::triangle()
{
	length = 2;
	width  = 3;
	height = 4;
}
void triangle::display()
{
	printf("%d,%d,%d\n",length,width,height);
}
void triangle::displayFirst(triangle *pthis)
{
	pthis->display();
}
triangle::~triangle()
{
}

void *midCall(triangle * tri)
{
	triangle::displayFirst(tri);
}
int main()
{
//pthread_t id;

triangle *tri = new triangle;

typedef void (*nPtr)(triangle *);//自定义指针函数
nPtr p;
p = (nPtr)triangle::displayFirst;
p(tri);

//pthread_create(&id,NULL,(void *)midCall,tri);

//pthread_join(id,NULL);

delete tri;

return 0;
}
#include <stdio.h>
#include <pthread.h>
#include <iostream>

class triangle
{
	private:
		int length;
		int width;
		int height;

	public:
		triangle();
		virtual ~triangle();
		static void displayFirst(triangle *pthis);
		void display();
};

triangle::triangle()
{
	length = 2;
	width  = 3;
	height = 4;
}
void triangle::display()
{
	printf("%d,%d,%d\n",length,width,height);
}
void triangle::displayFirst(triangle *pthis)
{
	pthis->display();
}
triangle::~triangle()
{
}

void *midCall(void *)
{
	//printf("a = %d\n",*a);
	triangle *tri = new triangle;
	triangle::displayFirst(tri);
	delete tri;
}
int main()
{
	pthread_t id;

	//int a = 9;
	//int *p = &a;

	pthread_create(&id,NULL,midCall,NULL);

	pthread_join(id,NULL);	

	return 0;
}
#include <stdio.h>
#include <pthread.h>
#include <iostream>

class triangle
{
	private:
		int length;
		int width;
		int height;

	public:
		triangle();
		virtual ~triangle();
		static void displayFirst(triangle *pthis);
		void display();
};

triangle::triangle()
{
	length = 2;
	width  = 3;
	height = 4;
}
void triangle::display()
{
	printf("%d,%d,%d\n",length,width,height);
}
void triangle::displayFirst(triangle *pthis)
{
	pthis->display();
}
triangle::~triangle()
{
}

void *midCall(void *arg)
{
	triangle *tri = (triangle *)arg;
	//triangle::displayFirst(tri);
	tri->display();
	
}
int main()
{
	pthread_t id;
	
	triangle *tri = new triangle;
	
	pthread_create(&id,NULL,midCall,(void *)tri);//must be the type of the void pointer.
	pthread_join(id,NULL);	
	
	delete tri;
	
	return 0;
}
#include <stdio.h>
#include <pthread.h>
#include <iostream>
//g++ -lpthread -o cpro cpro.cpp
class triangle
{
	private:
		int length;
		int width;
		int height;

	public:
		triangle();
		virtual ~triangle();
		static void displayFirst(triangle *pthis);
		void display();
};

triangle::triangle()
{
	length = 2;
	width  = 3;
	height = 4;
}
void triangle::display()
{
	printf("%d,%d,%d\n",length,width,height);
}
void triangle::displayFirst(triangle *pthis)
{
	pthis->display();
}
triangle::~triangle()
{
}

void *midCall(void *arg)
{
	triangle *tri = (triangle *)arg;
	triangle::displayFirst(tri);
	
}
int main()
{
	pthread_t id;
	
	triangle *tri = new triangle;
	
	pthread_create(&id,NULL,midCall,(void *)tri);//must be the type of the void pointer.
	pthread_join(id,NULL);	
	
	delete tri;
	
	return 0;
}

#ifndef UNISE_THREAD_H_
#define UNISE_THREAD_H_

#include <cstdlib>
#include <errno.h>
#include <pthread.h>
#include <string>

#include "unise/base.h"

namespace unise
{

/// @brief 简单线程处理逻辑的封装基类,用户仅需要实现 run 接口。
/// @note 支持一些基本的线程操作接口。如果需要对线程运行进行较为复杂的操作,
/// 建议不要直接使用此基类。
class Thread
{
public:
    Thread(const std::string& name):
        _tid(0), _name(name) {
    }

    virtual ~Thread() {
    }

    /// @brief 获取线程名
    /// @return
    const std::string& get_name() {
        return _name;
    }

    /// @brief 获取线程id
    /// @return 线程的 thread id
    pthread_t get_tid() {
        return _tid;
    }

    /// @brief 强制取消线程对象对应的线程的执行
    /// @return 与 pthread_cancel 返回语义相同
    int cancel() {
        int ret = ESRCH;
        if (0 != _tid) {
            ret = pthread_cancel(_tid);
            if (0 != ret) {
                UWARNING("[\tlvl=FOLLOW\t] FAIL: pthread_cancel(name=%s, tid=%d) return %d",
                        get_name().c_str(), _tid, ret);
            } else {
                _tid = 0;
            }
        }
        return ret;
    }

    /// @brief 给线程发送一个信号
    /// @note 这个操作保证信号处理函数在对应线程的上下文中执行,但可能影响整个进程。
    /// @return 与 pthread_kill 返回语义相同
    int kill(int sig = SIGTERM) {
        int ret = ESRCH;
        if (0 != _tid) {
            ret = pthread_kill(_tid, sig);
            if (0 != ret) {
                UWARNING("[\tlvl=FOLLOW\t] FAIL: pthread_kill(name=%s, tid=%d, signal=%d) "
                            "return %d", get_name().c_str(), _tid, sig, ret);
            } else {
                _tid = 0;
            }
        }
        return ret;
    }

    /// @brief 将线程分离,使其自己处理回收资源。
    /// @return
    virtual int detach() {
        int ret = ESRCH;
        if (0 != _tid) {
            ret = pthread_detach(_tid);
            if (0 != ret) {
                UWARNING("[\tlvl=FOLLOW\t] FAIL: pthread_detach(name=%s, tid=%d) return %d",
                        get_name().c_str(), _tid, ret);
            }
        }
        return ret;
    }

    /// @brief 调用该函数join本线程
    /// @return
    virtual int join() {
        int ret = ESRCH;
        if (0 != _tid) {
            ret = pthread_join(_tid, NULL);
            if (0 != ret) {
                UWARNING("[\tlvl=FOLLOW\t] FAIL: pthread_join(name=%s, tid=%d) return %d",
                        get_name().c_str(), _tid, ret);
            } else {
                _tid = 0;
            }
        }
        return ret;
    }

    /// @brief 子类实现该函数以自定义线程函数
    /// @return
    virtual int run() = 0;

    /// @brief 调用该函数启动线程
    /// @return 与 pthread_create 的返回值含义相同
    virtual int start() {
        UTRACE("Start thread(%s).", get_name().c_str());
        int ret = pthread_create(&_tid, NULL, _run_thread, (void *)this);
        if (0 != ret) {
            UWARNING("[\tlvl=FOLLOW\t] FAIL: pthread_create(name=%s) return %d",
                        get_name().c_str(), ret);
        }
        return ret;
    }

protected:
    /// @brief 退出线程,在run函数中调用,不应该在外部调用。
    /// @param[in] p 退出参数,返回给 join 调用的信息
    void exit(void *p) {
        if (0 != get_tid()) {
            pthread_exit(p);
        }
    }

private:

    /// @brief 线程函数,就是在pthread_create传入的函数
    /// @param[in|out] para : 用于传入给线程处理的数据
    /// @return
    static void* _run_thread(void *para) {
        com_openlog_r();    // 不检查返回值
        Thread *t = reinterpret_cast<Thread*>(para);
        UNOTICE("Thread(name=%s, tid=%d) running.", t->get_name().c_str(),
                t->get_tid());
        int ret = t->run();
        UNOTICE("Thread(name=%s, tid=%d) exit, return %d", t->get_name().c_str(),
                t->get_tid(), ret);
        com_closelog_r();
        return NULL;
    }

private:
    pthread_t   _tid;       ///< 线程ID
    std::string _name;      ///< 线程名
};

}   // namespace unise

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值