【问题标题】:two semaphores not communicating两个信号量不通信
【发布时间】:2016-05-31 08:48:35
【问题描述】:

我有一个使用信号量的客户端服务器项目。 我从同一个文件夹运行两者,它们使用相同的密钥。 现在,我希望服务器锁定信号量,因此客户端在服务器释放它之前无法运行命令,但客户端忽略服务器的锁定。我不明白我的错误在哪里。服务器代码:

#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <signal.h>
#include <sys/shm.h>
#include <sys/stat.h>
#define FLAGS IPC_CREAT | 0644
union semun {
    int val;
    struct semid_ds *buf;
    ushort *array; };
union semun semarg;
struct sembuf sops[1];
int main() {
    semarg.val=1;
    int resultsCreator=open("results.txt",O_CREAT|O_RDWR);
    key_t key;
    key = ftok("results.txt", 'k');
    int shmid = shmget(key, 12, FLAGS);
    int semfor = semget(key, 1, IPC_CREAT | IPC_EXCL | 0666);
    semctl ( semfor , 0 , SETVAL , semarg );
    sops->sem_num = 0;
    sops->sem_flg = 0;
    sops->sem_op = -1;
    int k = semop ( semfor , sops , 1 ); //lock the semaphore
    char* shmaddr;
    int numWaiting =0;
    while(1){   
        sleep(2); //CHECK EVERY 2 SECONDS IF SOMEONE IS WAITING
        numWaiting = semctl(semfor, 0, GETNCNT, semarg); 
        if(numWaiting==0){  
            printf("none waiting\n");
            continue; }
        printf("more than one waiter\n");  //NEVER GETS HERE
    } //END WHILE

客户端代码:

#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <signal.h>
#include <sys/shm.h>
#include <sys/stat.h>
#define FLAGS IPC_CREAT | 0644
union semun {
    int val;
    struct semid_ds *buf;
    ushort *array;
};   
union semun semarg;
struct sembuf sops[1];
int main()
{
    key_t key;
    key = ftok("results.txt", 'k');
    int shmid = shmget(key, 12, FLAGS);
    semarg.val=1;
    int semfor = semget(key, 0, 0666);
    semctl ( semfor , 0 , SETVAL , semarg );
    sops->sem_num = 0;
    sops->sem_flg = 0;
    sops->sem_op = -1;
    semop ( semfor , sops , 1 );
    printf("skipped lock\n"); //PRINTS IT, EVEN WHEN IT'S STILL LOCKED
    sops->sem_op = 1;
    semop ( semfor , sops , 1 );
    return 0;
}

为什么客户端会忽略服务器的信号量锁?

【问题讨论】:

  • 真实代码是否也漏掉了任何错误检查?
  • /我删除了一些不重要的部分以使其尽可能短,但我的代码没有错误,我在这里展示了它打印的内容
  • 我删除了一些不重要的部分 如果你不知道它为什么不起作用,你就无法知道哪些部分是不重要的。打印 semget() 的返回值 - 每次运行它。
  • 我对每个系统调用都有这个检查,我删除了它,因为它从不指向错误(从不返回 -1)
  • 保留代码中的所有错误检查,让它只在发生错误时向stderr 输出消息。

标签: c linux locking semaphore


【解决方案1】:

我回答了一个类似的问题,所以我将它复制到这里

如果您是技术人员,如果您要在线程之间同步任务,您应该使用 Semaphore。在解析之前读取输入的示例。 Here's 信号量的答案。

但是,如果您使用共享资源,并且需要避免竞争条件/两个线程同时访问,则应该使用互斥锁。 Here's 一个关于什么是互斥锁的问题。

还可以看看 Michael Barr 的 disambiguation,它真的很棒。

我会彻底阅读问题和消歧,您实际上可能最终不使用信号量而只使用互斥锁,因为根据您的解释,您只是控制共享资源。

常用信号量函数

int sem_init(sem_t *sem, int pshared, unsigned int value); //Use pshared with 0, starts the semaphore with a given value

int sem_wait(sem_t *sem);//decreases the value of a semaphore, if it's in 0 it waits until it's increased

int sem_post(sem_t *sem);//increases the semaphore by 1

int sem_getvalue(sem_t *sem, int *valp);// returns in valp the value of the semaphore the returned int is error control

int sem_destroy(sem_t *sem);//destroys a semaphore created with sim_init

通用互斥锁函数(适用于 unix)

int pthread_mutex_init(pthread_mutex_t *p_mutex, const pthread_mutexattr_t *attr); //starts mutex pointed by p_mutex, use attr NULL for simple use

int pthread_mutex_lock(pthread_mutex_t *p_mutex); //locks the mutex

int pthread_mutex_unlock(pthread_mutex_t *p_mutex); //unlocks the mutex

int pthread_mutex_destroy(pthread_mutex_t *p_mutex);//destroys the mutex

我不确定您的代码为什么不起作用,但根据您的解释,您不需要使用信号量,因为客户端和服务器之间没有同步,只有使用共享资源。尝试使用互斥体重写信号量部分,您会发现它看起来更自然,并且可能最终会解决问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-24
    • 1970-01-01
    • 2021-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多