2.我想要将一个主线程中的函数被创建的线程调用怎么办?
35 个解决方案
#1
线程没有函数,没有变量
函数和变量都是资源 内存地址
你的问题是,怎么让子线程访问主线程使用过的资源
_beginthreadex函数不是有个参数么,可以传过去 去认真看下这个函数的用法
函数和变量都是资源 内存地址
你的问题是,怎么让子线程访问主线程使用过的资源
_beginthreadex函数不是有个参数么,可以传过去 去认真看下这个函数的用法
#2

#3
全局变量,传参都可以。
#4
函数和全局变量是一致的,线程中可以直接使用。
线程创建者的堆栈变量,通过参数传递过去,必须保诚线程在使用时的有效性,也就是要做好同步。
分配的堆空间也是一样的。
线程创建者的堆栈变量,通过参数传递过去,必须保诚线程在使用时的有效性,也就是要做好同步。
分配的堆空间也是一样的。
#5
全局变量没法申明,我申明的是static cstring path;然后这个就被报错,说是不能这么写,我是写在头文件中的
#6
函数等同于全局变量这个没用啊,因为这个函数中调用的是主进程中的变量,而如果调用它,线程是没有权限获取主进程中的变量的
#7
如果当作参数传递过去是要做成struct啊,这个结构体如何制作函数呢?
#8
头文件中不应该定义变量啊,应该在cpp中定义,可以在头文件中外部声明:
例如:
global.cpp中
#include "global.h"
int g_iVal = 10;
...
global.h中
#pragma once
extern int g_iVal;
例如:
global.cpp中
#include "global.h"
int g_iVal = 10;
...
global.h中
#pragma once
extern int g_iVal;
#9
创建线程的时候要传至少一个参数,把所有你想要这个线程使用的变量封装到一个结构体内,把这个结构体的指针传给线程
#10
你确定这么写是对的?我需要在主进程中获取到该变量的值,然后让子线程也能访问获取到该值哦
#11
嗯嗯,是我没说清楚,就是我做了一个函数,我要用子线程调用该函数,但是该函数的实现都在主进程中,请问怎么将该函数封装到结构体中啊?
#12
主线程和子线程地位完全相同
我想你说的“该函数的实现在主进程中”,指的是该函数功能不独立,混杂在主线程负责处理的任务中
如果是这样,请整理自己的代码,分清哪些代码是必须由主线程处理的,哪些代码本身功能独立不需要和任何一个线程绑定
#13
#14
恩,是的,但是因为这个操作我的主线程中已经实现过了,我想要直接调用那个函数来实现,如果不调用那个函数,那我就需要在子线程中重新做主线程中做过的步骤了。所以请问有没有什么办法可以实现这个步骤吗?这个函数就是发个嘟嘟的声音,所以我只要调用,不需要获得什么,请问有办法吗?
如果该函数是全局函数,直接在子线程里调用,如果并非全局可见,传函数指针
如果该函数是某个对象的成员函数,在确保不会线程冲突的前提下,把该对象的指针传给子线程,如果有可能发生线程冲突,在该函数内使用线程锁保护冲突代码
#15
其实我这个就是子线程结束的时候调用一下这个函数,但是子线程结束我开个定时器等着,怎么都感觉浪费啊
#16
#17
#18
请问函数指针怎么调用呢??
看半天没看明白什么需求,你还是大致写几行代码描述下吧。函数怎么还是属于某个线程的?
#19
你在写mfc程序嘛?创建线程的时候将this指针传给线程,他的函数随便调。
createthread(NULL,0,ThreadFunc,this,0,&id);
dword winapi ThreadFunc(void* lparam)
{
Object* dlg = (Object*)this;
....
}
createthread(NULL,0,ThreadFunc,this,0,&id);
dword winapi ThreadFunc(void* lparam)
{
Object* dlg = (Object*)this;
....
}
#20
把this指针传进去,通过this指针调用函数
#21
1.AfxBeginThread(FindDiskProc, (LPVOID)(this), THREAD_PRIORITY_NORMAL , 0,0 , NULL);//this指主窗口对象指针
2.在操作函数
UNIT myThreadProc(LPVOID lpParameter){
CxxxmainDlg *pMain=(CxxxmainDlg*)lpParameter;// 得到主窗口
//调用变量
pMain->age.....................
return 0
}
2.在操作函数
UNIT myThreadProc(LPVOID lpParameter){
CxxxmainDlg *pMain=(CxxxmainDlg*)lpParameter;// 得到主窗口
//调用变量
pMain->age.....................
return 0
}
#22
你在写mfc程序嘛?创建线程的时候将this指针传给线程,他的函数随便调。
createthread(NULL,0,ThreadFunc,this,0,&id);
dword winapi ThreadFunc(void* lparam)
{
Object* dlg = (Object*)this;
....
}
#23
#24
getPath没有加锁?读数据的时候要等待其他线程的数据写入结束。
#25
其实可能是我没有讲清楚,就是我创建了一个线程,然后这个线程运行完成之后我需要做别的操作,但是现在我不希望主进程用waitforsingleobject来等待,因为主进程我还需要接收别的命令,所以请问有没有什么方法来让我在主进程中获取线程结束的?我用了一个本办法1毫秒询问一个全局变量,但是这个我个人觉得太浪费cpu了,所以请问各位有没有什么好办法??
#26
其实可能是我没有讲清楚,就是我创建了一个线程,然后这个线程运行完成之后我需要做别的操作,但是现在我不希望主进程用waitforsingleobject来等待,因为主进程我还需要接收别的命令,所以请问有没有什么方法来让我在主进程中获取线程结束的?我用了一个本办法1毫秒询问一个全局变量,但是这个我个人觉得太浪费cpu了,所以请问各位有没有什么好办法??
接收别的命令?不是可以用waitformultipleobjects这个函数?
#27
或者你使用队列将主线程所有想处理的命令全部push队列中,主线程就去pop,然后用一个switch case...
#28
其实可能是我没有讲清楚,就是我创建了一个线程,然后这个线程运行完成之后我需要做别的操作,但是现在我不希望主进程用waitforsingleobject来等待,因为主进程我还需要接收别的命令,所以请问有没有什么方法来让我在主进程中获取线程结束的?我用了一个本办法1毫秒询问一个全局变量,但是这个我个人觉得太浪费cpu了,所以请问各位有没有什么好办法??
发通知或者回调,将回调函数传给子线程,子线程结束前调用回调函数
#29
或者你使用队列将主线程所有想处理的命令全部push队列中,主线程就去pop,然后用一个switch case...
#30
#31
子线程 A B C
主线程 M
M需要得到 A B C操作完成的命令,那么分别在A B C 完成后往队列中push完成消息 并且标记如:A_MSG ,B_MSG, C_MSG
M线程不断的从队列中取出消息,分别处理A_MSG ,B_MSG, C_MSG
这个消息就可以在放一些自定义的数据...
如果只是简单的命令,只是通知 还是用waitformultipleobjects
主线程 M
M需要得到 A B C操作完成的命令,那么分别在A B C 完成后往队列中push完成消息 并且标记如:A_MSG ,B_MSG, C_MSG
M线程不断的从队列中取出消息,分别处理A_MSG ,B_MSG, C_MSG
这个消息就可以在放一些自定义的数据...
如果只是简单的命令,只是通知 还是用waitformultipleobjects
#32
楼上说的回调,其实回调的执行体还是子线程在执行 不是主线程
#33
仅供参考
//循环向a函数每次发送200个字节长度(这个是固定的)的buffer,
//a函数中需要将循环传进来的buffer,组成240字节(也是固定的)的新buffer进行处理,
//在处理的时候每次从新buffer中取两个字节打印
#ifdef WIN32
#pragma warning(disable:4996)
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#include <windows.h>
#include <process.h>
#include <io.h>
#define MYVOID void
#define vsnprintf _vsnprintf
#else
#include <unistd.h>
#include <sys/time.h>
#include <pthread.h>
#define CRITICAL_SECTION pthread_mutex_t
#define MYVOID void *
#endif
//Log{
#define MAXLOGSIZE 20000000
#define MAXLINSIZE 16000
#include <time.h>
#include <sys/timeb.h>
#include <stdarg.h>
char logfilename1[]="MyLog1.log";
char logfilename2[]="MyLog2.log";
static char logstr[MAXLINSIZE+1];
char datestr[16];
char timestr[16];
char mss[4];
CRITICAL_SECTION cs_log;
FILE *flog;
#ifdef WIN32
void Lock(CRITICAL_SECTION *l) {
EnterCriticalSection(l);
}
void Unlock(CRITICAL_SECTION *l) {
LeaveCriticalSection(l);
}
void sleep_ms(int ms) {
Sleep(ms);
}
#else
void Lock(CRITICAL_SECTION *l) {
pthread_mutex_lock(l);
}
void Unlock(CRITICAL_SECTION *l) {
pthread_mutex_unlock(l);
}
void sleep_ms(int ms) {
usleep(ms*1000);
}
#endif
void LogV(const char *pszFmt,va_list argp) {
struct tm *now;
struct timeb tb;
if (NULL==pszFmt||0==pszFmt[0]) return;
vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);
ftime(&tb);
now=localtime(&tb.time);
sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);
sprintf(timestr,"%02d:%02d:%02d",now->tm_hour ,now->tm_min ,now->tm_sec );
sprintf(mss,"%03d",tb.millitm);
printf("%s %s.%s %s",datestr,timestr,mss,logstr);
flog=fopen(logfilename1,"a");
if (NULL!=flog) {
fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);
if (ftell(flog)>MAXLOGSIZE) {
fclose(flog);
if (rename(logfilename1,logfilename2)) {
remove(logfilename2);
rename(logfilename1,logfilename2);
}
} else {
fclose(flog);
}
}
}
void Log(const char *pszFmt,...) {
va_list argp;
Lock(&cs_log);
va_start(argp,pszFmt);
LogV(pszFmt,argp);
va_end(argp);
Unlock(&cs_log);
}
//Log}
#define ASIZE 200
#define BSIZE 240
#define CSIZE 2
char Abuf[ASIZE];
char Cbuf[CSIZE];
CRITICAL_SECTION cs_HEX ;
CRITICAL_SECTION cs_BBB ;
struct FIFO_BUFFER {
int head;
int tail;
int size;
char data[BSIZE];
} BBB;
int No_Loop=0;
void HexDump(int cn,char *buf,int len) {
int i,j,k;
char binstr[80];
Lock(&cs_HEX);
for (i=0;i<len;i++) {
if (0==(i%16)) {
sprintf(binstr,"%03d %04x -",cn,i);
sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
} else if (15==(i%16)) {
sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
sprintf(binstr,"%s ",binstr);
for (j=i-15;j<=i;j++) {
sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
}
Log("%s\n",binstr);
} else {
sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
}
}
if (0!=(i%16)) {
k=16-(i%16);
for (j=0;j<k;j++) {
sprintf(binstr,"%s ",binstr);
}
sprintf(binstr,"%s ",binstr);
k=16-k;
for (j=i-k;j<i;j++) {
sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
}
Log("%s\n",binstr);
}
Unlock(&cs_HEX);
}
int GetFromRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {
int lent,len1,len2;
lent=0;
Lock(cs);
if (fbuf->size>=len) {
lent=len;
if (fbuf->head+lent>BSIZE) {
len1=BSIZE-fbuf->head;
memcpy(buf ,fbuf->data+fbuf->head,len1);
len2=lent-len1;
memcpy(buf+len1,fbuf->data ,len2);
fbuf->head=len2;
} else {
memcpy(buf ,fbuf->data+fbuf->head,lent);
fbuf->head+=lent;
}
fbuf->size-=lent;
}
Unlock(cs);
return lent;
}
MYVOID thdB(void *pcn) {
char *recv_buf;
int recv_nbytes;
int cn;
int wc;
int pb;
cn=(int)pcn;
Log("%03d thdB thread begin...\n",cn);
while (1) {
sleep_ms(10);
recv_buf=(char *)Cbuf;
recv_nbytes=CSIZE;
wc=0;
while (1) {
pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);
if (pb) {
Log("%03d recv %d bytes\n",cn,pb);
HexDump(cn,recv_buf,pb);
sleep_ms(1);
} else {
sleep_ms(1000);
}
if (No_Loop) break;//
wc++;
if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);
}
if (No_Loop) break;//
}
#ifndef WIN32
pthread_exit(NULL);
#endif
}
int PutToRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {
int lent,len1,len2;
Lock(cs);
lent=len;
if (fbuf->size+lent>BSIZE) {
lent=BSIZE-fbuf->size;
}
if (fbuf->tail+lent>BSIZE) {
len1=BSIZE-fbuf->tail;
memcpy(fbuf->data+fbuf->tail,buf ,len1);
len2=lent-len1;
memcpy(fbuf->data ,buf+len1,len2);
fbuf->tail=len2;
} else {
memcpy(fbuf->data+fbuf->tail,buf ,lent);
fbuf->tail+=lent;
}
fbuf->size+=lent;
Unlock(cs);
return lent;
}
MYVOID thdA(void *pcn) {
char *send_buf;
int send_nbytes;
int cn;
int wc;
int a;
int pa;
cn=(int)pcn;
Log("%03d thdA thread begin...\n",cn);
a=0;
while (1) {
sleep_ms(100);
memset(Abuf,a,ASIZE);
a=(a+1)%256;
if (16==a) {No_Loop=1;break;}//去掉这句可以让程序一直循环直到按Ctrl+C或Ctrl+Break或当前目录下存在文件No_Loop
send_buf=(char *)Abuf;
send_nbytes=ASIZE;
Log("%03d sending %d bytes\n",cn,send_nbytes);
HexDump(cn,send_buf,send_nbytes);
wc=0;
while (1) {
pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);
Log("%03d sent %d bytes\n",cn,pa);
HexDump(cn,send_buf,pa);
send_buf+=pa;
send_nbytes-=pa;
if (send_nbytes<=0) break;//
sleep_ms(1000);
if (No_Loop) break;//
wc++;
if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);
}
if (No_Loop) break;//
}
#ifndef WIN32
pthread_exit(NULL);
#endif
}
int main() {
#ifdef WIN32
InitializeCriticalSection(&cs_log);
InitializeCriticalSection(&cs_HEX );
InitializeCriticalSection(&cs_BBB );
#else
pthread_t threads[2];
int threadsN;
int rc;
pthread_mutex_init(&cs_log,NULL);
pthread_mutex_init(&cs_HEX,NULL);
pthread_mutex_init(&cs_BBB,NULL);
#endif
Log("Start===========================================================\n");
BBB.head=0;
BBB.tail=0;
BBB.size=0;
#ifdef WIN32
_beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);
_beginthread((void(__cdecl *)(void *))thdB,0,(void *)2);
#else
threadsN=0;
rc=pthread_create(&(threads[threadsN++]),NULL,thdA,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);
rc=pthread_create(&(threads[threadsN++]),NULL,thdB,(void *)2);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);
#endif
if (!access("No_Loop",0)) {
remove("No_Loop");
if (!access("No_Loop",0)) {
No_Loop=1;
}
}
while (1) {
sleep_ms(1000);
if (No_Loop) break;//
if (!access("No_Loop",0)) {
No_Loop=1;
}
}
sleep_ms(3000);
Log("End=============================================================\n");
#ifdef WIN32
DeleteCriticalSection(&cs_BBB );
DeleteCriticalSection(&cs_HEX );
DeleteCriticalSection(&cs_log);
#else
pthread_mutex_destroy(&cs_BBB);
pthread_mutex_destroy(&cs_HEX);
pthread_mutex_destroy(&cs_log);
#endif
return 0;
}
#34
楼上这打日志 其实就是FIFO 消息队列例子
这样的话大小就得固定了,假如消息大小一直不固定,就得老是去修改代码
不是有std::queue 或者自己写个链表大小(动态分配)
这样的话大小就得固定了,假如消息大小一直不固定,就得老是去修改代码
不是有std::queue 或者自己写个链表大小(动态分配)

#35
楼上这打日志 其实就是FIFO 消息队列例子
这样的话大小就得固定了,假如消息大小一直不固定,就得老是去修改代码
不是有std::queue 或者自己写个链表大小(动态分配)![]()
你混淆了应用层消息大小和底层传输每次发送接收包的大小这两个概念。
#1
线程没有函数,没有变量
函数和变量都是资源 内存地址
你的问题是,怎么让子线程访问主线程使用过的资源
_beginthreadex函数不是有个参数么,可以传过去 去认真看下这个函数的用法
函数和变量都是资源 内存地址
你的问题是,怎么让子线程访问主线程使用过的资源
_beginthreadex函数不是有个参数么,可以传过去 去认真看下这个函数的用法
#2

#3
全局变量,传参都可以。
#4
函数和全局变量是一致的,线程中可以直接使用。
线程创建者的堆栈变量,通过参数传递过去,必须保诚线程在使用时的有效性,也就是要做好同步。
分配的堆空间也是一样的。
线程创建者的堆栈变量,通过参数传递过去,必须保诚线程在使用时的有效性,也就是要做好同步。
分配的堆空间也是一样的。
#5
全局变量,传参都可以。
#6
函数和全局变量是一致的,线程中可以直接使用。
线程创建者的堆栈变量,通过参数传递过去,必须保诚线程在使用时的有效性,也就是要做好同步。
分配的堆空间也是一样的。
#7
线程没有函数,没有变量
函数和变量都是资源 内存地址
你的问题是,怎么让子线程访问主线程使用过的资源
_beginthreadex函数不是有个参数么,可以传过去 去认真看下这个函数的用法
#8
头文件中不应该定义变量啊,应该在cpp中定义,可以在头文件中外部声明:
例如:
global.cpp中
#include "global.h"
int g_iVal = 10;
...
global.h中
#pragma once
extern int g_iVal;
例如:
global.cpp中
#include "global.h"
int g_iVal = 10;
...
global.h中
#pragma once
extern int g_iVal;
#9
创建线程的时候要传至少一个参数,把所有你想要这个线程使用的变量封装到一个结构体内,把这个结构体的指针传给线程
#10
#11
创建线程的时候要传至少一个参数,把所有你想要这个线程使用的变量封装到一个结构体内,把这个结构体的指针传给线程
#12
嗯嗯,是我没说清楚,就是我做了一个函数,我要用子线程调用该函数,但是该函数的实现都在主进程中,请问怎么将该函数封装到结构体中啊?
创建线程的时候要传至少一个参数,把所有你想要这个线程使用的变量封装到一个结构体内,把这个结构体的指针传给线程
主线程和子线程地位完全相同
我想你说的“该函数的实现在主进程中”,指的是该函数功能不独立,混杂在主线程负责处理的任务中
如果是这样,请整理自己的代码,分清哪些代码是必须由主线程处理的,哪些代码本身功能独立不需要和任何一个线程绑定
#13
#14
恩,是的,但是因为这个操作我的主线程中已经实现过了,我想要直接调用那个函数来实现,如果不调用那个函数,那我就需要在子线程中重新做主线程中做过的步骤了。所以请问有没有什么办法可以实现这个步骤吗?这个函数就是发个嘟嘟的声音,所以我只要调用,不需要获得什么,请问有办法吗?
如果该函数是全局函数,直接在子线程里调用,如果并非全局可见,传函数指针
如果该函数是某个对象的成员函数,在确保不会线程冲突的前提下,把该对象的指针传给子线程,如果有可能发生线程冲突,在该函数内使用线程锁保护冲突代码
#15
其实我这个就是子线程结束的时候调用一下这个函数,但是子线程结束我开个定时器等着,怎么都感觉浪费啊
#16
#17
#18
请问函数指针怎么调用呢??
看半天没看明白什么需求,你还是大致写几行代码描述下吧。函数怎么还是属于某个线程的?
#19
你在写mfc程序嘛?创建线程的时候将this指针传给线程,他的函数随便调。
createthread(NULL,0,ThreadFunc,this,0,&id);
dword winapi ThreadFunc(void* lparam)
{
Object* dlg = (Object*)this;
....
}
createthread(NULL,0,ThreadFunc,this,0,&id);
dword winapi ThreadFunc(void* lparam)
{
Object* dlg = (Object*)this;
....
}
#20
把this指针传进去,通过this指针调用函数
#21
1.AfxBeginThread(FindDiskProc, (LPVOID)(this), THREAD_PRIORITY_NORMAL , 0,0 , NULL);//this指主窗口对象指针
2.在操作函数
UNIT myThreadProc(LPVOID lpParameter){
CxxxmainDlg *pMain=(CxxxmainDlg*)lpParameter;// 得到主窗口
//调用变量
pMain->age.....................
return 0
}
2.在操作函数
UNIT myThreadProc(LPVOID lpParameter){
CxxxmainDlg *pMain=(CxxxmainDlg*)lpParameter;// 得到主窗口
//调用变量
pMain->age.....................
return 0
}
#22
你在写mfc程序嘛?创建线程的时候将this指针传给线程,他的函数随便调。
createthread(NULL,0,ThreadFunc,this,0,&id);
dword winapi ThreadFunc(void* lparam)
{
Object* dlg = (Object*)this;
....
}
#23
#24
getPath没有加锁?读数据的时候要等待其他线程的数据写入结束。
#25
其实可能是我没有讲清楚,就是我创建了一个线程,然后这个线程运行完成之后我需要做别的操作,但是现在我不希望主进程用waitforsingleobject来等待,因为主进程我还需要接收别的命令,所以请问有没有什么方法来让我在主进程中获取线程结束的?我用了一个本办法1毫秒询问一个全局变量,但是这个我个人觉得太浪费cpu了,所以请问各位有没有什么好办法??
#26
其实可能是我没有讲清楚,就是我创建了一个线程,然后这个线程运行完成之后我需要做别的操作,但是现在我不希望主进程用waitforsingleobject来等待,因为主进程我还需要接收别的命令,所以请问有没有什么方法来让我在主进程中获取线程结束的?我用了一个本办法1毫秒询问一个全局变量,但是这个我个人觉得太浪费cpu了,所以请问各位有没有什么好办法??
接收别的命令?不是可以用waitformultipleobjects这个函数?
#27
或者你使用队列将主线程所有想处理的命令全部push队列中,主线程就去pop,然后用一个switch case...
#28
其实可能是我没有讲清楚,就是我创建了一个线程,然后这个线程运行完成之后我需要做别的操作,但是现在我不希望主进程用waitforsingleobject来等待,因为主进程我还需要接收别的命令,所以请问有没有什么方法来让我在主进程中获取线程结束的?我用了一个本办法1毫秒询问一个全局变量,但是这个我个人觉得太浪费cpu了,所以请问各位有没有什么好办法??
发通知或者回调,将回调函数传给子线程,子线程结束前调用回调函数
#29
或者你使用队列将主线程所有想处理的命令全部push队列中,主线程就去pop,然后用一个switch case...
#30
#31
子线程 A B C
主线程 M
M需要得到 A B C操作完成的命令,那么分别在A B C 完成后往队列中push完成消息 并且标记如:A_MSG ,B_MSG, C_MSG
M线程不断的从队列中取出消息,分别处理A_MSG ,B_MSG, C_MSG
这个消息就可以在放一些自定义的数据...
如果只是简单的命令,只是通知 还是用waitformultipleobjects
主线程 M
M需要得到 A B C操作完成的命令,那么分别在A B C 完成后往队列中push完成消息 并且标记如:A_MSG ,B_MSG, C_MSG
M线程不断的从队列中取出消息,分别处理A_MSG ,B_MSG, C_MSG
这个消息就可以在放一些自定义的数据...
如果只是简单的命令,只是通知 还是用waitformultipleobjects
#32
楼上说的回调,其实回调的执行体还是子线程在执行 不是主线程
#33
仅供参考
//循环向a函数每次发送200个字节长度(这个是固定的)的buffer,
//a函数中需要将循环传进来的buffer,组成240字节(也是固定的)的新buffer进行处理,
//在处理的时候每次从新buffer中取两个字节打印
#ifdef WIN32
#pragma warning(disable:4996)
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#include <windows.h>
#include <process.h>
#include <io.h>
#define MYVOID void
#define vsnprintf _vsnprintf
#else
#include <unistd.h>
#include <sys/time.h>
#include <pthread.h>
#define CRITICAL_SECTION pthread_mutex_t
#define MYVOID void *
#endif
//Log{
#define MAXLOGSIZE 20000000
#define MAXLINSIZE 16000
#include <time.h>
#include <sys/timeb.h>
#include <stdarg.h>
char logfilename1[]="MyLog1.log";
char logfilename2[]="MyLog2.log";
static char logstr[MAXLINSIZE+1];
char datestr[16];
char timestr[16];
char mss[4];
CRITICAL_SECTION cs_log;
FILE *flog;
#ifdef WIN32
void Lock(CRITICAL_SECTION *l) {
EnterCriticalSection(l);
}
void Unlock(CRITICAL_SECTION *l) {
LeaveCriticalSection(l);
}
void sleep_ms(int ms) {
Sleep(ms);
}
#else
void Lock(CRITICAL_SECTION *l) {
pthread_mutex_lock(l);
}
void Unlock(CRITICAL_SECTION *l) {
pthread_mutex_unlock(l);
}
void sleep_ms(int ms) {
usleep(ms*1000);
}
#endif
void LogV(const char *pszFmt,va_list argp) {
struct tm *now;
struct timeb tb;
if (NULL==pszFmt||0==pszFmt[0]) return;
vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);
ftime(&tb);
now=localtime(&tb.time);
sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);
sprintf(timestr,"%02d:%02d:%02d",now->tm_hour ,now->tm_min ,now->tm_sec );
sprintf(mss,"%03d",tb.millitm);
printf("%s %s.%s %s",datestr,timestr,mss,logstr);
flog=fopen(logfilename1,"a");
if (NULL!=flog) {
fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);
if (ftell(flog)>MAXLOGSIZE) {
fclose(flog);
if (rename(logfilename1,logfilename2)) {
remove(logfilename2);
rename(logfilename1,logfilename2);
}
} else {
fclose(flog);
}
}
}
void Log(const char *pszFmt,...) {
va_list argp;
Lock(&cs_log);
va_start(argp,pszFmt);
LogV(pszFmt,argp);
va_end(argp);
Unlock(&cs_log);
}
//Log}
#define ASIZE 200
#define BSIZE 240
#define CSIZE 2
char Abuf[ASIZE];
char Cbuf[CSIZE];
CRITICAL_SECTION cs_HEX ;
CRITICAL_SECTION cs_BBB ;
struct FIFO_BUFFER {
int head;
int tail;
int size;
char data[BSIZE];
} BBB;
int No_Loop=0;
void HexDump(int cn,char *buf,int len) {
int i,j,k;
char binstr[80];
Lock(&cs_HEX);
for (i=0;i<len;i++) {
if (0==(i%16)) {
sprintf(binstr,"%03d %04x -",cn,i);
sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
} else if (15==(i%16)) {
sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
sprintf(binstr,"%s ",binstr);
for (j=i-15;j<=i;j++) {
sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
}
Log("%s\n",binstr);
} else {
sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
}
}
if (0!=(i%16)) {
k=16-(i%16);
for (j=0;j<k;j++) {
sprintf(binstr,"%s ",binstr);
}
sprintf(binstr,"%s ",binstr);
k=16-k;
for (j=i-k;j<i;j++) {
sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
}
Log("%s\n",binstr);
}
Unlock(&cs_HEX);
}
int GetFromRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {
int lent,len1,len2;
lent=0;
Lock(cs);
if (fbuf->size>=len) {
lent=len;
if (fbuf->head+lent>BSIZE) {
len1=BSIZE-fbuf->head;
memcpy(buf ,fbuf->data+fbuf->head,len1);
len2=lent-len1;
memcpy(buf+len1,fbuf->data ,len2);
fbuf->head=len2;
} else {
memcpy(buf ,fbuf->data+fbuf->head,lent);
fbuf->head+=lent;
}
fbuf->size-=lent;
}
Unlock(cs);
return lent;
}
MYVOID thdB(void *pcn) {
char *recv_buf;
int recv_nbytes;
int cn;
int wc;
int pb;
cn=(int)pcn;
Log("%03d thdB thread begin...\n",cn);
while (1) {
sleep_ms(10);
recv_buf=(char *)Cbuf;
recv_nbytes=CSIZE;
wc=0;
while (1) {
pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);
if (pb) {
Log("%03d recv %d bytes\n",cn,pb);
HexDump(cn,recv_buf,pb);
sleep_ms(1);
} else {
sleep_ms(1000);
}
if (No_Loop) break;//
wc++;
if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);
}
if (No_Loop) break;//
}
#ifndef WIN32
pthread_exit(NULL);
#endif
}
int PutToRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {
int lent,len1,len2;
Lock(cs);
lent=len;
if (fbuf->size+lent>BSIZE) {
lent=BSIZE-fbuf->size;
}
if (fbuf->tail+lent>BSIZE) {
len1=BSIZE-fbuf->tail;
memcpy(fbuf->data+fbuf->tail,buf ,len1);
len2=lent-len1;
memcpy(fbuf->data ,buf+len1,len2);
fbuf->tail=len2;
} else {
memcpy(fbuf->data+fbuf->tail,buf ,lent);
fbuf->tail+=lent;
}
fbuf->size+=lent;
Unlock(cs);
return lent;
}
MYVOID thdA(void *pcn) {
char *send_buf;
int send_nbytes;
int cn;
int wc;
int a;
int pa;
cn=(int)pcn;
Log("%03d thdA thread begin...\n",cn);
a=0;
while (1) {
sleep_ms(100);
memset(Abuf,a,ASIZE);
a=(a+1)%256;
if (16==a) {No_Loop=1;break;}//去掉这句可以让程序一直循环直到按Ctrl+C或Ctrl+Break或当前目录下存在文件No_Loop
send_buf=(char *)Abuf;
send_nbytes=ASIZE;
Log("%03d sending %d bytes\n",cn,send_nbytes);
HexDump(cn,send_buf,send_nbytes);
wc=0;
while (1) {
pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);
Log("%03d sent %d bytes\n",cn,pa);
HexDump(cn,send_buf,pa);
send_buf+=pa;
send_nbytes-=pa;
if (send_nbytes<=0) break;//
sleep_ms(1000);
if (No_Loop) break;//
wc++;
if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);
}
if (No_Loop) break;//
}
#ifndef WIN32
pthread_exit(NULL);
#endif
}
int main() {
#ifdef WIN32
InitializeCriticalSection(&cs_log);
InitializeCriticalSection(&cs_HEX );
InitializeCriticalSection(&cs_BBB );
#else
pthread_t threads[2];
int threadsN;
int rc;
pthread_mutex_init(&cs_log,NULL);
pthread_mutex_init(&cs_HEX,NULL);
pthread_mutex_init(&cs_BBB,NULL);
#endif
Log("Start===========================================================\n");
BBB.head=0;
BBB.tail=0;
BBB.size=0;
#ifdef WIN32
_beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);
_beginthread((void(__cdecl *)(void *))thdB,0,(void *)2);
#else
threadsN=0;
rc=pthread_create(&(threads[threadsN++]),NULL,thdA,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);
rc=pthread_create(&(threads[threadsN++]),NULL,thdB,(void *)2);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);
#endif
if (!access("No_Loop",0)) {
remove("No_Loop");
if (!access("No_Loop",0)) {
No_Loop=1;
}
}
while (1) {
sleep_ms(1000);
if (No_Loop) break;//
if (!access("No_Loop",0)) {
No_Loop=1;
}
}
sleep_ms(3000);
Log("End=============================================================\n");
#ifdef WIN32
DeleteCriticalSection(&cs_BBB );
DeleteCriticalSection(&cs_HEX );
DeleteCriticalSection(&cs_log);
#else
pthread_mutex_destroy(&cs_BBB);
pthread_mutex_destroy(&cs_HEX);
pthread_mutex_destroy(&cs_log);
#endif
return 0;
}
#34
楼上这打日志 其实就是FIFO 消息队列例子
这样的话大小就得固定了,假如消息大小一直不固定,就得老是去修改代码
不是有std::queue 或者自己写个链表大小(动态分配)
这样的话大小就得固定了,假如消息大小一直不固定,就得老是去修改代码
不是有std::queue 或者自己写个链表大小(动态分配)

#35
楼上这打日志 其实就是FIFO 消息队列例子
这样的话大小就得固定了,假如消息大小一直不固定,就得老是去修改代码
不是有std::queue 或者自己写个链表大小(动态分配)![]()
你混淆了应用层消息大小和底层传输每次发送接收包的大小这两个概念。