0

我有一个代码如下。它在访问信号量时崩溃,并且我创建了“命名信号量”,崩溃后我无法从命令提示符删除。如何使用命令提示实用程序删除它们?该代码试图创建可以从 2 个生产者(玩家)命令提示符和一个消费者(结果)命令提示符运行的 Rock,Paper,Scissors 游戏。我也很感激有关修复/更正/改进代码的建议。

//compiled by executing --> gcc -pthread logic.c  -lrt

#include <stdio.h>
#include <sys/shm.h>
#include <semaphore.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <sys/fcntl.h>
#include <sys/mman.h>

//don't need an exec call just based on paramters run the processes

typedef struct sync_tools
{
    int pid;
    void* shm_ptr;
    sem_t* sem_array[2];
} sync_tools;

void producer(void * ctx)
{
    char choice;
    sync_tools *ctxt=(sync_tools*)ctx;

    while(1)
    {
        printf ("Enter the following for input \n");
        printf ("R. Rock\n");
        printf ("P. Paper\n");
        printf ("S. Scissors\n");
        scanf ("%c",&choice);
    
        if (ctxt->pid==1)
        {    
            printf ("Process1\n");
            sem_wait(ctxt->sem_array[0]);
            sprintf((char*) ctxt->shm_ptr, "%c\n", choice);
            sem_post(ctxt->sem_array[0]);
            printf ("Process1\n");
        }
        else
        {
            printf ("Process2\n");
            sem_wait(ctxt->sem_array[1]);
            sprintf((char*) (ctxt->shm_ptr+1), "%c\n", choice);
            sem_post(ctxt->sem_array[1]);
        }
    }
}

//need 2 semphores for sync
void consumer(void *ctx)
{
    sync_tools *ctxt=(sync_tools*)ctx;
    char data[2]={0x00};
    int flag=1;
    while(1)
    {
        sem_wait(ctxt->sem_array[0]);
        sem_wait(ctxt->sem_array[1]);
        scanf ((char *) ctxt->shm_ptr, "%c", &data[0]);
        scanf ((char *) (ctxt->shm_ptr+1), "%c", &data[1]);
        switch(data[0])
        {
            case 'R':
            case 'r':
                if ((data[1] =='p')|| (data[1]=='P'));
                    flag=0;
            break;
            case'P':
            case'p':    
                if ((data[1] =='s')|| (data[1]=='S'));
                    flag=0;
            break;
            case 's':
            case'S':
                if ((data[1] =='R')|| (data[1]=='R'));
                    flag=0;
            break;
        }   
        if (flag)
            printf("Process 1 wins \n");
        else
            printf("Process 2 wins \n");
        sem_post(ctxt->sem_array[0]);
        sem_post(ctxt->sem_array[1]);
    }

}

int main (int argc, char* argv[])
{
    char choice;
    int SIZE=4096;
    char *name="SHM_WQ";
    sync_tools cntxt={}; //initialize without memset
    //calling sem_open as I want a named semaphore which is not locally available by copy like in forked processes.
    cntxt.sem_array[0]= sem_open ("P1C", O_CREAT | O_EXCL, 0644, 1); 
    cntxt.sem_array[1]= sem_open ("P2C", O_CREAT | O_EXCL, 0644, 1); 
        /* shared memory file descriptor */
        int shm_fd;

        /* pointer to shared memory object */
        void* ptr;

        /* create the shared memory object */
        shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
        /* configure the size of the shared memory object */
        ftruncate(shm_fd, SIZE);

        /* memory map the shared memory object */
        ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0); //sys/mman.h 
        cntxt.shm_ptr=ptr;
        //pass the shared memory and semaphores to all the threads and spawn them
        if(strcmp(argv[1], "p1") == 0)
        cntxt.pid=1;
    else if (strcmp(argv[1], "p2") ==0)
        cntxt.pid=2;
    else if (strcmp(argv[1], "c") ==0)
        cntxt.pid=3;//don't care
        producer(&cntxt);
        consumer(&cntxt);
}
4

1 回答 1

0

修改我的代码如下:

    cntxt.sem_array[0] = sem_open("P1C", 0);
    cntxt.sem_array[1] = sem_open("P2C", 0);
    if (cntxt.sem_array[0] == NULL)
    {
            cntxt.sem_array[0]= sem_open ("P1C", O_CREAT | O_EXCL, 0644, 2);
    }
    if (cntxt.sem_array[1] == NULL)
    {
            cntxt.sem_array[1]= sem_open ("P2C", O_CREAT | O_EXCL, 0644, 2);
    }
    if ((cntxt.sem_array[0] == NULL) || (cntxt.sem_array[1] == NULL))
            printf("SEM_OPEN ERROR");

还如评论中所述,创建了一个小实用程序,该实用程序采用 semname 并将其与内核取消链接。

于 2022-02-14T10:32:54.030 回答