C++ 下编译pthread的问题

hanb99 2007-04-11 11:03:32
开始我是这样写的
void* startListen(void *)
{
........
}
/////
pthread_create(&socketListen,NULL, startListen, NULL);
这个时候是可以正常编译的,也能执行。

可是我想把它写到一个类中封装起来,改为如下:
void* AcdSocket::startListen(void *)
{........}
pthread_create(&socketListen,NULL, (void *)startListen, NULL);
报错:
错误: invalid use of member (did you forget the ‘&’ ?)

//////////
再改为:
void AcdSocket::startListen(void *)
{........}
pthread_create(&socketListen,NULL, (void *)&startListen, NULL);
报错:
错误: 从类型 ‘void*’ 到类型 ‘void* (*)(void*)’ 的转换无效

编译语句:
g++ main.cpp acdsocket.cpp -lpthread -o acd
g++版本
g++ (GCC) 4.0.3 (Ubuntu 4.0.3-1ubuntu5)
系统:
ubuntu 6.06
...全文
847 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
mathe 2007-04-12
  • 打赏
  • 举报
回复
不能够将类成员变量函数作为普通函数指针使用。
可以再写一个函数:
AcdSocket socket;
void* startListen(void *s)
{
return socket.startListen(s);
}

就可以了
pottichu 2007-04-12
  • 打赏
  • 举报
回复
startListen 要么是静态 函数, 要么是全局函数.
qingcairousi 2007-04-12
  • 打赏
  • 举报
回复
很简单的原因
所有的非静态的成员函数的第一个参数都是一个隐式的this指针,因此
void AcdSocket::startListen(void *)等价于
static void AcdSocket::startListen(AcdSocket* this,void *)
这个函数声明当然和pthread所要求的函数类型不同,自然pthread_create不会接受
所以你要做的就是写一个static函数,static函数不会有隐式的this指针
iu_81 2007-04-11
  • 打赏
  • 举报
回复
pthread_create(&socketListen,NULL, &AcdSocket::startListen, NULL);
iambic 2007-04-11
  • 打赏
  • 举报
回复
AcdSocket::startListen是一个成员函数的指针,你是不能强制转化成函数指针的。

而且它调用的时候实际接受两个参数,一个是this,一个是void*。你可以考虑再写一个普通函数或类的静态函数,在这个函数内部接受一个void*,然后把这个void*转化为AcdSocket指针,再通过这个指针调用相应的成员函数。
hanb99 2007-04-11
  • 打赏
  • 举报
回复
void* AcdSocket::startListen(void *)
{........}
pthread_create(&socketListen,NULL, &startListen, NULL);

行不通呀:
错误: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say ‘&acdsocket::AcdSocket::startListen’
错误: cannot convert ‘void* (acdsocket::AcdSocket::*)(void*)’ to ‘void* (*)(void*)’ for argument ‘3’ to ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)’
iu_81 2007-04-11
  • 打赏
  • 举报
回复
void* AcdSocket::startListen(void *)
{........}
pthread_create(&socketListen,NULL, &startListen, NULL);
不想低调 2007-04-11
  • 打赏
  • 举报
回复
mark
hzhxxx 2007-04-11
  • 打赏
  • 举报
回复


/*****************************************************************
1. 以下是研究 mysql 5.0.22 得出的结果,描述并使用标准 c++演
示了使用 MySQLC API 函数 简单操作数据库的流程;
例子程序在 VC6(VC7.1) + windows 2000 上调试通过;
例子程序在 red hat linux 9,red fc6 上调试通过

2. 版权归 黄志辉 所有,可以自由修改发布,请保留作者信息,请记
住能共享的好东西要共享,做一个有良心的好程序员

3. 有什么技术可探讨. qq: 84075167
*****************************************************************/

#ifdef WIN32
#include <windows.h>
typedef unsigned long APIRETURN;
typedef unsigned long (__stdcall * funcptr)(void *);
#else
#include <pthread.h>
#include <unistd.h>
typedef void * APIRETURN;
#endif

#include <iostream>
#include <errmsg.h>
#include <time.h>

using namespace std;

/*****************************************************************/
///name : main
//function : 主测试函数
//access : private
//para :
// 1. : int argc
// : 系统参数个数
// 2. : char * argv[]
// : 参数数值
//return : 返回给 startup 函数的退出参数
//author : hzh
//date : 2006-06-24
/*****************************************************************/

#include "../db/connectpool.h"

using namespace std;

#include <mysql.h>

APIRETURN insert(void * para)
{
for(;;)
{
for(int i = 0;i < 200;++i)
{
CMysqlClient client;
CMysqlStore store;
if(!store.SetTransAction(client.GetConnect()))
{
//std::cout<<"db connect pool busy on insert"<<endl;
break;
}
std::string s_sql = "";
s_sql = "insert into processingtransactioninterface";
s_sql += "(acttype,resourceid,actresult,memo) values(";
s_sql += "1,1,1,'发的沙')";
if(!store.Exec(s_sql))
{
//执行SQL语句出错
store.RollBack();
std::cout<<"execute insert syntax fail,"<<store.What().c_str()<<endl;
}
else
{
store.Commit();
}
}

#ifdef WIN32
Sleep(DWORD(1000 * 0.01));
#else
sleep(1);
#endif

}
return 0;
}

APIRETURN update(void * para)
{
for(;;)
{
for(;;)
{
CMysqlClient client;
CMysqlStore store;
if(!store.SetTransAction(client.GetConnect()))
{
//std::cout<<"db connect pool busy on update"<<endl;
break;
}
std::string s_sql = "";
s_sql = "update processingtransactioninterface";
s_sql += " set acttype=2,memo='aaa杀',actresult=3";
s_sql += " where acttype = 1";
if(!store.Exec(s_sql))
{
//执行SQL语句出错
store.RollBack();
std::cout<<"execute update syntax fail,"<<store.What().c_str()<<endl;
}
else
{
store.Commit();
}
break;
}
#ifdef WIN32
Sleep(DWORD(1000 * 0.01));
#else
sleep(1);
#endif

}

return 0;
}

APIRETURN show(void * para)
{
for(;;)
{
for(;;)
{
CMysqlClient client;
CMysqlStore store;
if(!store.SetTransAction(client.GetConnect()))
{
//std::cout<<"db connect pool busy on show"<<endl;
break;
}

/*
这可能发生,例如,如果你正在使用mysql_use_result()
并且在你已经调用了mysql_free_result()之前试图
执行新查询。如果你在mysql_use_result()或
mysql_store_result()之间试图执行返回数
据的2个查询,它也可能发生。*/

std::string s_sql = "select * from processingtransactioninterface";
if(!store.Query(s_sql))
{
//删除表失败
std::cout<<"query table fail,"<<store.What().c_str()<<endl;

}
else
{
for(unsigned long i = 0;i <store.RowCount();++i)
{
std::cout<<"result:"<<store.GetItemLong(i,"actresult")
<<"\tmemo:"<<store.GetItemString(i,"memo").c_str()
<<"\tactid:"<<store.GetItemLong(i,0)<<endl;
}

s_sql = "delete from processingtransactioninterface";
if(!store.Exec(s_sql))
{
//删除表失败
store.RollBack();
std::cout<<"delete table fail,"<<store.What().c_str()<<endl;
}
else
{
store.Commit();
}
}
break;
}

#ifdef WIN32
Sleep(DWORD(1000 * 0.1));
#else
sleep(10);
#endif
}
return 0;
}

int main( int argc, char * argv[] )
{
for(int i = 0;i < 3;++i)
{
std::string host = "127.0.0.1";
std::string user = "root";
std::string password = "mysql5";
std::string dbname = "test";
unsigned int port = MYSQL_PORT;
CConnect * conn = new CMysqlConnect();
conn->Connect(host,user,password,dbname,port);
CConnPool::Instance().Add(conn);
}

CMysqlClient client;
CMysqlStore store;
store.SetTransAction(client.GetConnect());

//先删除数据表
std::string s_sql = "drop table processingtransactioninterface";
if(!store.Exec(s_sql))
{
//删除表失败
std::cout<<"drop table fail"<<endl<<store.What().c_str()<<endl;
}
else
{
std::cout<<"drop table success"<<endl;
}

//创建数据表,字段 actid 设置了自增列属性
s_sql = "create table processingtransactioninterface(";
s_sql += "actid integer not null AUTO_INCREMENT,";
s_sql += "acttype integer not null,resourceid integer not null,";
s_sql += " subresoureid integer, actdate varchar(19), actresult integer,";
s_sql += " memo varchar(50) null,primary key(actid))";
if(!store.Exec(s_sql))
{
//创建表失败
std::cout<<"create table fail"<<endl;
return -1;
}
else
{
std::cout<<"create table success"<<endl;
std::cout<<s_sql.c_str()<<endl;
}


#ifdef WIN32
unsigned long p1 = 0;
::CreateThread(0,0,(funcptr)show,0,0,&p1);
#else
pthread_t p1 = 0;
pthread_create(&p1,0,show,0);
#endif


#ifdef WIN32
unsigned long p2 = 0;
::CreateThread(0,0,(funcptr)update,0,0,&p1);
#else
pthread_t p2 = 0;
pthread_create(&p2,0,update,0);
#endif

#ifdef WIN32
unsigned long p3 = 0;
::CreateThread(0,0,(funcptr)insert,0,0,&p1);
#else
pthread_t p3 = 0;
pthread_create(&p1,0,insert,0);
#endif

#ifdef WIN32
system("pause");
#else
pause();
#endif

return 1;
}





hanb99 2007-04-11
  • 打赏
  • 举报
回复
iambic() 大大,这么说我不太懂,可以给出具体要怎么做吗
hanb99 2007-04-11
  • 打赏
  • 举报
回复
iu_81(黄云万里动风色,白波九道流雪山。)大大,还是不好用呀,555555555555~~~~~~`
错误: cannot convert ‘void* (acdsocket::AcdSocket::*)(void*)’ to ‘void* (*)(void*)’ for argument ‘3’ to ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)’


65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧