C语言中信号量未按预期工作的客户端/服务器程序问题
客户端/服务器程序消息处理异常
我正在开发一个客户端/服务器程序,服务器通过信号量避免同时接收多条消息出错,但实际运行不符合预期:
测试场景与异常表现
测试
cli_test.c,发送num1=10、num2=-1:- 实际输出:
Client: message received :20.000000.
Client: message received :-1. - 预期输出:
Client: message received :20.000000.
Client: message received :Invalid number.
- 实际输出:
修改为
num1=-12、num2=-1:- 实际输出:
Client: message received :-1.
Client: message received :Invalid number. - 预期输出:两条
Client: message received :Invalid number.
- 实际输出:
修改为
num1=12、num2=1:- 实际输出:
Client: message received :24.000000.
Client: message received :1.000000. - 预期输出:
24.000000和2.000000
- 实际输出:
可见服务器仅正确处理一条消息,另一条未计算直接返回原数值。
服务器代码(server.c)
#include <sys/msg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <unistd.h> #include <sys/sem.h> #include <time.h> #include <semaphore.h> typedef struct { long id; char mes[20]; } message; double calculate(int num){ return num*2; } struct sembuf semaphore_operations[1]; int main() { // key key_t cle = ftok(".", 0); if (cle == -1) { perror("ftok"); return -1; } // message queue int msqId = msgget(cle, IPC_CREAT | 0700); if (msqId == -1) { perror("msgget"); return -1; } // semaphore int semId = semget(cle, 1, IPC_CREAT | 0700); if (semId == -1) { perror("semget"); return -1; } if (semctl(semId, 0, SETVAL, 1) == -1) { perror("semctl"); return -1; } semaphore_operations[0].sem_num = 0; semaphore_operations[0].sem_flg = 0; message mes; while (1) { semaphore_operations[0].sem_op = -1; if (semop(semId, semaphore_operations, 1) == -1) { perror("semop"); return -1; } // wait for message (blocked) int received = msgrcv(msqId, &mes, sizeof(message) - sizeof(long), 0, 0); if (received == -1) { perror("msgrcv"); return -1; } int num_mat = atoi(mes.mes); printf("Server: message received :%d.\n", num_mat); if(num_mat > 0) { double result = calculate(num_mat); char result_str[20] = ""; sprintf(result_str, "%f", result); strcpy(mes.mes, result_str); int sent = msgsnd(msqId, &mes, sizeof(message) - sizeof(long), 0); if (sent == -1) { perror("msgsnd"); return -1; } printf("Server: message sent.\n"); } else { strcpy(mes.mes, "Invalid number"); int sent = msgsnd(msqId, &mes, sizeof(message)-sizeof(long), 0); if(sent == -1){ perror("msgsnd"); return -1; } } // signal the semaphore semaphore_operations[0].sem_op = 1; if (semop(semId, semaphore_operations, 1) == -1) { perror("semop"); return -1; } } // remove when server shut down msgctl(msqId, IPC_RMID, NULL); semctl(semId, 0, IPC_RMID, 0); return 0; }
客户端测试代码(cli_test.c)
#include <sys/msg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <unistd.h> #include <sys/sem.h> #include <time.h> #include <semaphore.h> #include <pthread.h> typedef struct { long id; char mes[20]; } message; void* client_thread(void* arg) { key_t cle = ftok(".", 0); if (cle == -1) { perror("ftok"); pthread_exit(NULL); } int msqId = msgget(cle, 0); if (msqId == -1) { perror("msgget"); pthread_exit(NULL); } message mes; mes.id = 1; int num = *((int*) arg); sprintf(mes.mes, "%d", num); // send message to the server int sent = msgsnd(msqId, &mes, sizeof(message) - sizeof(long), 0); if (sent == -1) { perror("msgsnd"); pthread_exit(NULL); } // receive the result message result; int received = msgrcv(msqId, &result, sizeof(message) - sizeof(long), 0, 0); if (received == -1) { perror("msgrcv"); pthread_exit(NULL); } printf("Client: message received :%s.\n", result.mes); pthread_exit(NULL); } int main() { pthread_t client1, client2; int num1 = 10, num2 = -1; if (pthread_create(&client1, NULL, client_thread, &num1) != 0) { perror("pthread_create"); return -1; } if (pthread_create(&client2, NULL, client_thread, &num2) != 0) { perror("pthread_create"); return -1; } pthread_join(client1, NULL); pthread_join(client2, NULL); return 0; }
内容的提问来源于stack exchange,提问作者Hangel
相关产品推荐
相关产品推荐

