我正在尝试在客户端和服务器程序中实现线程,二进制信号量和消息队列。一切正常,除了我的服务器中的回复,以将响应发送回客户端。当我取消注释回复时,服务器在收到消息后无限循环。
它们都使用message.h头文件,该文件是包含以下内容的结构: contents(字符),id(int)和mtype(int)。
// server.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include "message.h"
int sqid, cqid, pid;
msg m, n;
sem_t sem_var;
key_t key;
void requestSem();
void setSem();
void unlockSem();
void reply();
void readQueue();
void listener(void *ptr);
int main() {
key = ftok(".", 'z');
sqid = msgget(key, IPC_CREAT | 0600);
if(sqid < 0) {
perror("Error creating the message queue.\n");
}
pthread_t thread1;
pthread_t thread2;
pthread_t thread3;
char *msg1 = "Thread 1";
char *msg2 = "Thread 2";
char *msg3 = "Thread 3";
pthread_create(&thread1, NULL, (void *) &listener, (void *) msg1);
pthread_create(&thread2, NULL, (void *) &listener, (void *) msg2);
pthread_create(&thread3, NULL, (void *) &listener, (void *) msg3);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_join(thread3, NULL);
}
// always listen for messages
void listener(void *ptr) {
while (1) {
requestSem();
setSem();
readQueue();
unlockSem();
//reply();
}
}
void readQueue()
{
// print the proccess ID and thread ID
printf("Process ID: %d, Thread ID: %d\n", getpid(), pthread_self());
// receive message
if(msgrcv(sqid,&m,sizeof(struct msg),0,0) < 0) {
perror("Error receiving a message.\n");
}
printf("Message was received...\n");
fprintf(stderr, "The contents are: %s\n", &m.contents);
fprintf(stderr, "The client's ID is: %d\n", (&m)->id);
fprintf(stderr, "The thread's ID is: %d\n", pthread_self());
}
void requestSem()
{
// request semaphore (lock)
sem_init(&sem_var, 1, 1);
printf("Semaphore requested.\n");
}
void setSem()
{
// lock semaphore
sem_wait(&sem_var);
printf("Semaphore set.\n");
}
void unlockSem()
{
// unlock semaphore
sem_post(&sem_var);
printf("Semaphore unlocked.\n");
}
void reply()
{
// send reply
printf("got here\n");
pid = (&m)->id;
cqid = msgget(pid, 0600);
n.contents = (&m)->contents;
n.mtype = 0;
n.id = getpid();
if(msgsnd(cqid, &n,sizeof(struct msg),0) < 0) {
perror("Msg send error");
}
msgctl(sqid,IPC_RMID,NULL);
}
// client.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <errno.h>
#include <pthread.h>
#include <semaphore.h>
#include "message.h"
int main() {
// initialize variables
int mqid, rqid;
msg m;
key_t key;
// initialize message
int pid;
pid = getpid();
m.id = pid;
m.mtype = 1;
// create message queue and response queue
key = ftok(".", 'z');
mqid = msgget(key, 0600);
rqid = msgget(pid, IPC_CREAT | 0600);
if(mqid < 0) {
perror("Error creating the message queue.\n");
}
if (rqid < 0)
{
perror("Error creating the message queue.\n");
}
// loop forever, can send as many messages as you want
while(1) {
fprintf(stderr, "The ID of the client is: %d\n", pid);
// prompt for user input
printf("Enter one character to send: \n");
scanf("%s", &m.contents);
// send message
if(msgsnd(mqid, &m,sizeof(struct msg), 1) < 0) {
perror("Error sending the message.");
}
//msgctl(mqid,IPC_RMID,NULL);
printf("Message was sent successfully!\n");
// receive response
printf("Waiting for a reply...\n");
if(msgrcv(rqid,&m,sizeof(msg), 0, 0) < 0)
{
perror("Error receiving a message.\n");
}
printf("Message was received.\n");
fprintf(stderr, "The contents are: %s\n", &m.contents);
}
}
提前感谢您的帮助。当回复在服务器的监听器中被注释掉时,一切都正常运行。取消注释会产生无限循环。
答案 0 :(得分:0)
服务器永不退出的原因是因为每个线程都有
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000145201ac0
Triggered by Thread: 7
Thread 7 name:
Thread 7 Crashed:
0 libsystem_platform.dylib 0x0000000199e36220 _platform_memmove + 48 (memmove.s:220)
1 CoreImage 0x0000000184e86e4c CI::GLTextureManager::texture_for_CGImage(CGImage*, CI::PixelFormat) + 372 (context-gles.cpp:910)
2 CoreImage 0x0000000184e8a310 CI::GLContext::bind_textures(CI::SerialObjectPtrArray*, CI::Kernel*) + 240 (context-gles.cpp:3060)
3 CoreImage 0x0000000184e899e0 CI::GLContext::render_apply_node(CI::Node const*, bool) + 160 (context-gles.cpp:2699)
4 CoreImage 0x0000000184e897fc CI::GLContext::recursive_render(CI::Node*, bool) + 912 (context-gles.cpp:2379)
5 CoreImage 0x0000000184e8a788 CI::GLContext::render(CI::Node*) + 180 (context-gles.cpp:2880)
6 CoreImage 0x0000000184e9bfec CI::_get_bitmap(CI::Context*, CI::Image*, CGRect, CGColorSpace*, CI::Bitmap*) + 676 (render.cpp:2622)
7 CoreImage 0x0000000184e9bc9c CI::image_get_bitmap(CI::Context*, CI::Image*, CGRect, CGColorSpace*, CI::Bitmap*, unsigned long) + 664 (render.cpp:2680)
8 CoreImage 0x0000000184ea08e8 copyImageBlockSetOptsCallback(void*, CGImageProvider*, CGRect, CGSize, __CFDictionary const*) + 856 (imageProvider.h:143)
9 CoreGraphics 0x0000000184af2198 CGImageProviderCopyImageBlockSet + 220 (CGImageProvider.c:500)
10 ImageIO 0x0000000185baa41c GetBytesImageProvider + 484 (CGImagePixelDataProvider.c:382)
11 ImageIO 0x0000000185c40440 _CGImagePluginWriteAppleJPEG + 2444 (imageAppleJPEG.c:2785)
12 ImageIO 0x0000000185ba3020 CGImageDestinationFinalize + 724 (CGImageDestination.c:2119)
13 MyAppNameHere 0x0000000100096468 _TFC11 MyAppNameHere 12PhotoEditor15fullImageOutputfS0_FT_GSqCSo22PHContentEditingOutput_ + 1272 (PhotoEditor.swift:71)
14 MyAppNameHere 0x0000000100113310 _TFFFFFC11 MyAppNameHere 36PhotosPickerCollectionViewController16editSingleAssetFS0_FCSo7PHAssetT_U_FT_T_U0_FTGSqCSo21PHContentEditingInput_GVSs10DictionaryCSo8NSObjectPSs9AnyObject___T_U_FT_T_U_FT_T_ + 172 (PhotosPickerCollectionViewController.swift:851)
15 libdispatch.dylib 0x0000000199c296e8 _dispatch_call_block_and_release + 24 (init.c:761)
16 libdispatch.dylib 0x0000000199c296a8 _dispatch_client_callout + 16 (object.m:513)
17 libdispatch.dylib 0x0000000199c37b40 _dispatch_root_queue_drain + 2140 (inline_internal.h:1063)
18 libdispatch.dylib 0x0000000199c372dc _dispatch_worker_thread3 + 112 (queue.c:4250)
19 libsystem_pthread.dylib 0x0000000199e3d470 _pthread_wqthread + 1092 (pthread.c:1990)
20 libsystem_pthread.dylib 0x0000000199e3d020 start_wqthread + 4 (pthread_asm.s:191)
循环,无法退出该循环