首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

C++ 下编译pthread的有关问题

2012-02-06 
C++ 下编译pthread的问题开始我是这样写的void*startListen(void*){........}/////pthread_create(&socket

C++ 下编译pthread的问题
开始我是这样写的
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

[解决办法]


/*****************************************************************
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;
}



[解决办法]
不能够将类成员变量函数作为普通函数指针使用。
可以再写一个函数:
AcdSocket socket;
void* startListen(void *s)
{
return socket.startListen(s);
}

就可以了
[解决办法]
很简单的原因
所有的非静态的成员函数的第一个参数都是一个隐式的this指针,因此
void AcdSocket::startListen(void *)等价于
static void AcdSocket::startListen(AcdSocket* this,void *)
这个函数声明当然和pthread所要求的函数类型不同,自然pthread_create不会接受
所以你要做的就是写一个static函数,static函数不会有隐式的this指针

热点排行