[英]error: Invalid argument; while sending msgsnd() message; not matching queue ID
[英]C system call msgsnd(): invalid argument error on certain compiler versions
好吧,我正在做一個大學項目,對這個愚蠢的問題感到抱歉。
我的任務是將字符串推入消息隊列,派生一個子進程並接收消息,然后通過同一消息隊列將響應發送回父進程,循環完成所有這些操作。
我已經在家里編寫了代碼,並且工作正常,但是部分任務是使其在大學服務器上工作,這是我遇到的問題。
這是我的代碼的相關部分:
父進程:
void fel2()
{
int messq, status;
key_t key = ftok("key", 1);
messq = msgget( key, 0600 | IPC_CREAT );
OpBike * ob_first = NULL;
ob_first = ob_read_in(ob_first);
char confirm_string[64];
while (exists_busy_bike(ob_first))
{
sleep(5);
ob_first = NULL;
ob_first = ob_read_in(ob_first);
int busy_bikes = count_busy_bikes(ob_first);
ob_first = NULL;
srand(time(NULL));
int bret = (rand() % busy_bikes);
ob_first = ob_read_in(ob_first);
ob_first = ob_read_in(ob_first);
int ret_bike_id = get_bikeid_by_jumps(ob_first, bret);
char ret_bike_id_char[64];
snprintf(ret_bike_id_char, 64, "%d", ret_bike_id);
send(messq, ret_bike_id_char);
fel2_child(messq, key);
ob_first = NULL;
wait(NULL);
strcpy(confirm_string, recv(messq));
ob_first = NULL;
ob_first = ob_read_in(ob_first);
wait(NULL);
}
status = msgctl( messq, IPC_RMID, NULL );
wait(NULL);
return;
}
子進程:
int fel2_child(int messq, key_t key)
{
pid_t child = fork();
if (child > 0) // parent process does nothing here
{
}
else { // child
char rbikeid[64];
strcpy(rbikeid, recv(messq));
OpBike * ob_first = NULL;
ob_first = ob_read_in(ob_first);
OpRent * or_first = NULL;
or_first = or_read_in(or_first);
OpBike * bike_ret = get_bike_by_bikeid(ob_first, rbikeid);
char check[64];
strcpy(check, bike_ret->bike_id);
ob_first = NULL;
ob_first = ob_read_in(ob_first);
or_add_return(or_first, ob_first, rbikeid);
ob_first = NULL;
ob_first = ob_read_in(ob_first);
OpBike * bike_check = get_bike_by_bikeid(ob_first, rbikeid);
strcpy(check, bike_check->bike_status);
send(messq, check);
exit(0);
}
return 0;
}
發送器和接收器功能:
int send( int messq, char * text )
{
struct message me = { 119, "asd" };
int status;
strcpy(me.mtext, text);
// THIS IS WHERE EVERYTHING GOES WRONG
status = msgsnd( messq, &me, strlen ( me.mtext ) + 1 , IPC_NOWAIT );
if ( status < 0 )
perror("msgsnd");
return 0;
}
char * recv( int messq)
{
struct message me;
int status;
status = msgrcv(messq, &me, 1024, 119, 0 );
if ( status < 0 )
perror("msgsnd");
char * ret;
ret = malloc(sizeof( char ) * strlen (me.mtext));
strcpy(ret, me.mtext);
return ret;
}
在家用計算機上運行上面的代碼可以正常工作。 運行Ubuntu 14.10,我的代碼使用gcc 4.9.1編譯。 但是,它在運行SLES 11 SP 1的學校服務器上不起作用,已經使用gcc 4.3.4編譯了代碼。
問題是我嘗試發送的字符串未正確發送。 它到達函數,被復制到消息結構中,然后在過程中消失,唯一回讀的是未定義的數據。
我現在有點想法了。 我曾嘗試將消息隊列的聲明放到其他地方(正如我的教授所建議的那樣),但這並不能解決問題。 我無法在學校服務器上更新編譯器,所以這就是我要處理的問題。 你們有沒有經歷過通過不同編譯器版本進行系統調用的奇怪行為? 有人知道如何解決此問題嗎?
感謝您的提前答復!
編輯2:結構消息的定義。
struct message {
long mtype;
char mtext [ 1024 ];
};
好的,事實證明,我的gcc版本(或Linux內核或我使用的任何軟件組件)會自動在ftok創建密鑰文件(請注意,“ key”在我的系統上不存在)。 高校服務器卻沒有。 所以
key_t key = ftok("argv[0]", 1);
要么
key_t key = ftok("filename", 1);
絕招。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.