QNX系列:五、资源管理器(3)简单的例子

资源管理器主要是解决多任务不阻塞的问题,系统提供封装好的函数给用户使用。在系统中服务器可以在不阻塞的条件下进行信号的接收并且进行数据处理工作。

这两个历程表示了大部分程序中的逻辑,比较重要的点总结如下:

  • 利用资源管理器可以方便的找到对应的文件,只需要open一个文件就行
  • 之后的传递数据就可以直接write,这一层的函数主要是进行与服务器的“资源管理器”的文件进行交互操作的
  • 对于信号的传递,可以方便的使用“回调函数”的方法进行,直接传递信号给客户端的fd文件标识符,
  • 对应那边只需要Reply一下,服务器就不会再阻塞,并进行下面的程序
  • 基本上这个过程在程序中只有单向运行,也就是説客户端传输数据给服务器,服务器进行数据处理(比如説dectect)
  • 假设每一个服务器都有一个“资源管理器”,那么系统就可以很方便的运转
  • 另外作为服务器而言,如果while循环去等待消息过来,那么这个时候服务器是received block的,也就是説只能处理一个来向的信号。这显然满足不了系统设计的要求,因爲不断有信号过来

解决了阻塞问题之后,服务器可以不断的接受信号并进行处理。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/neutrino.h>
#include <sys/dispatch.h> /*For _IO_MAX*/
#include <sys/mman.h>	/* for PROT_READ and so on*/
#include <fcntl.h>      /*for O_RDWR and so on*/
#include <sched.h>
#include <math.h>
/********************
#include "../jincheng2/msgtype.h"
int fd_detector;

int main(){
   msgtp msg;
   int replied;
   fd_detector = open(name,O_RDWR);
int count = 0;
   while(1){
   	short d1[100] = {1,2,3,4};
   	msg.type = _IO_MAX + 2;
   	MsgSend(fd_detector,&msg,sizeof(msg),&replied,sizeof(replied));
   	printf("Procl is end\n");
   	sleep(1);
   	//這邊寫一個d1的數組進去,那邊的緩存區就可以收到了
   	//真神奇
   	write(fd_detector,d1,sizeof(short)*100);
   	count++;
   	if(count==10){
   		break;
   	}
   }
}

这里的write函数调用了服务器进程中的资源管理器的io层的函数,并进行处理,该函数支持自己定义。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/neutrino.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>
#include <fcntl.h>      //for O_RDWR and so on
#include <sys/mman.h>	// for PROT_READ and so on

#include"msgtype.h"

int io_write (resmgr_context_t *ctp, io_write_t *msg, RESMGR_OCB_T *ocb);
static resmgr_connect_funcs_t  ConnectFuncs;
static resmgr_io_funcs_t       IoFuncs;
static iofunc_attr_t           IoFuncAttr;
int fd_sys_stat;
//char *buf;
short buf[108];

int replied;
//這個io_write函數是用來做什麽的?
//沒看出來有什麽用。

int	io_write (resmgr_context_t *ctp, io_write_t *msg, RESMGR_OCB_T *ocb)
{
   int     status,i;
   if ((status = iofunc_write_verify(ctp, msg, ocb, NULL)) != EOK)
       return (status);
   if (msg->i.xtype & _IO_XTYPE_MASK != _IO_XTYPE_NONE)
       return(ENOSYS);

   /* set up the number of bytes (returned by client's write()) */

   _IO_SET_WRITE_NBYTES (ctp, msg->i.nbytes);
   /*
    *  reread the data from the sender's message buffer.
    *  We're not assuming that all of the data fit into the
    *  resource manager library's receive buffer.
    */
   char *p = "sasdasd";
   sleep(1);
   resmgr_msgread(ctp, buf, msg->i.nbytes, sizeof(msg->i));
   printf("get the fuck write function\n%d\n",buf[0]);
   return (_RESMGR_NPARTS (0));
}

int message_callback( message_context_t *ctp, int type, unsigned flags, void *handle ){
   struct pdmsg_t *msg;
   int num;
   int i,k,j,m;	/*k:Track class; i:Temperorily used for loop*/

   /* cast a pointer to the message data */
   msg = (struct pdmsg_t *)ctp->msg;
   /* Build the reply message */
   num = type - _IO_MAX;
   switch (num){
   case OPTION1:
   	printf("1\n");
   case OPTION2:
   	printf("Get the Meessage : OPTION2\n");
   	MsgReply(ctp->rcvid,EOK , &replied,sizeof(int));
   	break;
   }
   return 0;
}
int main( int argc, char **argv )
{
   //打開讀取的進程
   int result = spawnl(P_NOWAIT, "/tmp/shm/get_data", "get_data", NULL);
   if (result == -1)
   {
   	perror("Error from spawnl");
   	exit(1);
   }
   //
   thread_pool_attr_t   pool_attr;
   resmgr_attr_t        resmgr_attr;
   message_attr_t       message_attr;
   dispatch_t           *dpp;
   thread_pool_t         *tpp;
   int                  resmgr_id, message_id;

   /* Create the Dispatch Interface 创建一个调度接口*/
   dpp = dispatch_create();
   if( dpp == NULL )
   {
       fprintf( stderr, "dispatch_create() failed: %s\n", strerror( errno ) );
       return EXIT_FAILURE;
   }
   memset( &resmgr_attr, 0, sizeof( resmgr_attr ) );//为开辟的内存设置一个值
   resmgr_attr.nparts_max = 1;
   resmgr_attr.msg_max_size = 2048;

   /* Setup the default I/O functions to handle open/read/write/... */
   iofunc_func_init( _RESMGR_CONNECT_NFUNCS, &ConnectFuncs,
                     _RESMGR_IO_NFUNCS, &IoFuncs );
   IoFuncs.write = io_write;//自己定義的函數,用來做write

   /* Setup the attribute for the entry in the filesystem */
   iofunc_attr_init( &IoFuncAttr, S_IFNAM | 0666, 0, 0 );
   //最重要的就是這個名字,有了這個名字之後就可以確定是哪一個資源了,實際上也是一個文件?
   resmgr_id = resmgr_attach( dpp, &resmgr_attr, name, _FTYPE_ANY, 0, &ConnectFuncs, &IoFuncs, &IoFuncAttr );
   if( resmgr_id == -1 )
   {
       fprintf( stderr, "resmgr_attach() failed: %s\n", strerror( errno ) );
       return EXIT_FAILURE;
   }

   /* Setup our message callback */
   memset( &message_attr, 0, sizeof( message_attr ) );
   message_attr.nparts_max = 1;
   message_attr.msg_max_size = 4096;

   printf("1---->here is the test\n");
   /* Attach a callback (handler) for two message types */
   message_id = message_attach( dpp, &message_attr, _IO_MAX + 1, _IO_MAX + 100, message_callback, NULL );
   if( message_id == -1 )
   {
       fprintf( stderr, "message_attach() failed: %s\n", strerror( errno ) );
       return EXIT_FAILURE;
   }

   memset(&pool_attr, 0, sizeof pool_attr);
   pool_attr.handle = dpp;
   pool_attr.context_alloc =dispatch_context_alloc;
   pool_attr.block_func =dispatch_block;
   pool_attr.handler_func =dispatch_handler;
   pool_attr.context_free =dispatch_context_free;
   pool_attr.lo_water = 2;
   pool_attr.hi_water = 4;
   pool_attr.increment = 1;
   pool_attr.maximum = 50;
   //创建线程池
   if((tpp = thread_pool_create(&pool_attr, POOL_FLAG_EXIT_SELF)) == NULL)
   {
       fprintf(stderr, "%s: Unable to initialize thread pool.\n", argv[0]);
       return EXIT_FAILURE;
   }

   thread_pool_start(tpp);//开启线程池
   return EXIT_SUCCESS;
}

这是一个比较简单的资源管理器。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

擦擦擦大侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值