Linux多线程同步之消息队列
创始人
2024-06-21 12:50:11
0

消息队列是消息的链表,存放在内核中并有消息队列标示符标示。

msgget用于创建一个新队列或打开一个现存的队列。msgsnd将新消息加入到消息队列中;每个消息包括一个long型的type;和消息缓存;msgrcv用于从队列中取出消息;取消息很智能,不一定先进先出

①msgget,创建一个新队列或打开一个现有队列

#include

int msgget ( key_t key, int flag );

//成功返回消息队列ID;错误返回-1

②msgsnd: 发送消息

#include

int msgsnd( int msgid, const void* ptr, size_t nbytes, int flag )

//成功返回0,错误返回-1

a:   flag可以指定为IPC_NOWAIT;  若消息队列已满,则msgsnd立即出错返回EABAIN;

若没指定IPC_NOWAIT; msgsnd会阻塞,直到消息队列有空间为止

③msgrcv: 读取消息:

ssize_t msgrcv( int msgid, void* ptr, size_t nbytes, long type, int flag );

a. type == 0; 返回消息队列中***个消息,先进先出

b. type > 0    返回消息队列中类型为tpye的***个消息

c. type < 0    返回消息队列中类型 <=  |type| 的数据;若这种消息有若干个,则取类型值最小的消息

消息队列创建步骤:

#define   MSG_FILE "."

struct msgtype {

long mtype;

char buffer[BUFFER+1];

};

if((key=ftok(MSG_FILE,'a'))==-1)

{

fprintf(stderr,"Creat Key Error:%s\n", strerror(errno));

exit(1);

}

if((msgid=msgget(key, IPC_CREAT | 0666/*PERM*/))==-1)

{

fprintf(stderr,"Creat Message  Error:%s\n", strerror(errno));

exit(1);

}

msg.mtype = 1;

strncpy(msg.buffer, argv[1], BUFFER);

msgsnd(msgid, &msg, sizeof(struct msgtype), 0);

msgrcv(msgid, &msg, sizeof(struct msgtype), 1, 0);

示例代码:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define   MSG_FILE "."

#define   BUFFER 255

#define   PERM S_IRUSR|S_IWUSR

#define IPCKEY 0x111

struct msgtype {

long mtype;

char buffer[BUFFER+1];

};

void* thr_test( void* arg ){

struct msgtype msg;

int msgid;

msgid =  *((int*)arg);

printf("msqid = %d  IPC_NOWAIT = %d\n", msgid, IPC_NOWAIT);

time_t tt = time(0)+8;

//while( time(0) <= tt )

//{

msgrcv(msgid, &msg, sizeof(struct msgtype), 1, 0);

fprintf(stderr,"Server Receive:%s\n", msg.buffer);

msg.mtype = 2;

msgsnd(msgid, &msg, sizeof(struct msgtype), 0);

//}

pthread_exit( (void*)2 );

}

int main(int argc, char **argv)

{

struct msgtype msg;

key_t key;

int msgid;

pthread_t tid;

if(argc != 2)

{

fprintf(stderr,"Usage:%s string\n", argv[0]);

exit(1);

}

/*

char path[256];

sprintf( path, "%s/", (char*)getenv("HOME") );

printf( "path is %s\n", path );

msgid=ftok( path, IPCKEY );

*/

if((key=ftok(MSG_FILE,'a'))==-1)

{

fprintf(stderr,"Creat Key Error:%s\n", strerror(errno));

exit(1);

}

if((msgid=msgget(key, IPC_CREAT | 0666/*PERM*/))==-1)

{

fprintf(stderr,"Creat Message  Error:%s\n", strerror(errno));

exit(1);

}

pthread_create( &tid, NULL, thr_test, &msgid );

fprintf(stderr,"msid is :%d\n", msgid);

msg.mtype = 1;

strncpy(msg.buffer, argv[1], BUFFER);

msgsnd(msgid, &msg, sizeof(struct msgtype), 0);

exit(0);

}
 

【编辑推荐】

  1. Linux多线程同步之命名管道
  2. linux多线程机制线程同步
  3. linux多线程之线程资源的释放

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
Windows恶意软件20年“... 在Windows的早期年代,病毒游走于系统之间,偶尔删除文件(但被删除的文件几乎都是可恢复的),并弹...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
着眼MAC地址,解救无法享受D... 在安装了DHCP服务器的局域网环境中,每一台工作站在上网之前,都要先从DHCP服务器那里享受到地址动...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...