向Linux登录终端发消息
同一台服务器,可能有很多个用户登录在上面,每个用户都是一个系统终端,可以向其他终端发送消息,同在服务器上开发的开发人员可以简单的互动(不能回复)一下哈!
一,效果
先登录一个终端,如下:
[root@localhost /]# who
root tty1 2013-02-16 18:14 (:0)
root pts/0 2013-02-17 02:01 (:0.0)
[root@localhost /]#
登录的终端为pts/0。然后再打开一个终端,如下:
[root@localhost /]# who
root tty1 2013-02-16 18:14 (:0)
root pts/0 2013-02-17 02:01 (:0.0)
root pts/1 2013-02-17 02:02 (:0.0)
[root@localhost /]#
此时登录的终端为pts/1。现在假设pts/1发消息给pts/0。
[root@localhost /]# write root pts/0
hello
在pts/0终端上收到消息如下:
[root@localhost /]#
Message from root@localhost.localdomain on pts/1 at 02:03 ...
hello
在pts/0上只是收到消息,不能回复的。
再看一下write命令的解释吧
WRITE(1) User Commands WRITE(1)
NAME
write - send a message to another user
SYNOPSIS
write user [ttyname]
DESCRIPTION
Write allows you to communicate with other users, by copying lines from
your terminal to theirs.
When you run the write command, the user you are writing to gets a mes‐
sage of the form:
Message from yourname@yourhost on yourtty at hh:mm ...
aio_read未定义的引用
下载了一份代码学习,发现编不过,这里需要修改CMakeLists.txt,可以参考编译错误: 对‘aio_read’未定义的引用
APUE 第七章 进程环境
C程序总是从main函数开始执行,main函数的原型是:
int main(int argc,char *argv[]);
其中argc是命令行参数的数目,argv是指向参数的各个指针所构成的数组。
多通道融合merge逻辑测试代码:
#include <iostream>
#include <queue>
#include <unordered_map>
#include <string>
class RecallItem {
public:
RecallItem() {};
RecallItem(const std::string &itemid_,const std::string &rec_id_,int score_) {
itemid = itemid_;
rec_id = rec_id_;
score = score_;
}
std::string itemid;
std::string rec_id;
int score;
};
struct ItemQueue {
std::vector<std::string> item_list;
std::string rec_id;
};
auto item_cmp = [](const RecallItem& a,const RecallItem& b) {
return a.score < b.score;
};
int main()
{
std::priority_queue<RecallItem,std::vector<RecallItem>,decltype(item_cmp)> queue_item(item_cmp);
std::unordered_map<std::string,ItemQueue > channel_map;
//权重信息
std::unordered_map<std::string,int > ch_weight {{"channel1",150},{"channel2",100}};
std::unordered_map<std::string,RecallItem> item_map;
//最大召回item个数
int max_merge_num = 100;
//构造两个召回通道 channel1,channel2
auto& channel1 = channel_map["channel1"];
channel1.rec_id = "1";
for(int i = 0;i < 200;i+=2)
channel1.item_list.push_back(std::to_string(i));
auto& channel2 = channel_map["channel2"];
channel2.rec_id = "2";
for(int i = 1;i < 200;i+=2)
channel2.item_list.push_back(std::to_string(i));
//遍历多个通道
for(auto ch : channel_map) {
int weight = 0;
//获取对应的权重信息
auto it = ch_weight.find(ch.first);
if(it != ch_weight.end()){
weight = ch_weight[ch.first];
}
int index = 0,count = 0;
int size = ch.second.item_list.size();
//对召回列表过滤 去重 调整分数权重
for(auto& item:ch.second.item_list) {
double rank_score = (0+weight) * 1.0 - index++;
auto iter = item_map.find(item);
if(iter != item_map.end()) {
//多个通道存在相同item,分数取较大者
if(iter->second.score < rank_score) {
iter->second.score = rank_score;
}
//记录多个通道命中的情况
iter->second.rec_id = iter->second.rec_id +"|" + ch.second.rec_id;
continue;
}
RecallItem ch_item(item,ch.second.rec_id,rank_score);
item_map.insert({item,ch_item});
}
}
for(auto item : item_map) {
queue_item.push(item.second);
}
std::vector<RecallItem> result;
while(!queue_item.empty() && result.size() < max_merge_num) {
auto item = queue_item.top();
auto iter = item_map.find(item.itemid);
if(iter != item_map.end()) {
item.rec_id = iter->second.rec_id;
}
result.emplace_back(item);
queue_item.pop();
}
for(auto res:result) {
std::cout <<"itemid:"<<res.itemid<<",rec_id:"<<res.rec_id<<std::endl;
}
#if 0
//debug print channel_map
for(auto ch:channel_map) {
for(auto& item:ch.second) {
std::cout << item <<" ";
}
std::cout <<std::endl;
}
#endif
return 0;
}