【问题标题】:Shared mutex in C error in InitInit 中的 C 错误中的共享互斥锁
【发布时间】:2015-08-27 15:44:01
【问题描述】:

我正在尝试创建一个具有共享内存的程序并执行多次相同的程序以增加一个值,所有这些都使用一个共享互斥锁。

问题是在我的第二次执行中,函数mutex_init 失败了。

有什么想法吗?

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <errno.h>
#include <mqueue.h>
#include <fcntl.h>
#include <pthread.h>
#include <unistd.h>

#define SM_SIZE sizeof (struct shared)
#define min 4
#define max 10

struct shared
{
    pthread_mutex_t mutex;
    int i;

};

char *shared1_name="asdf";


int main (int argc, char *argv[])
{

int id_sharedMem1;
int i,j,loops;
struct shared *memoriaC;

loops = atoi(argv[1]);

id_sharedMem1 = shm_open ( shared1_name , O_RDWR, 644 );    

if(id_sharedMem1==-1)
    {    
    id_sharedMem1 = shm_open ( shared1_name , O_CREAT|O_RDWR, 644 );
    if ( id_sharedMem1 == -1 || ftruncate ( id_sharedMem1, SM_SIZE ) == -1) 
        {
        printf("open %s\n",strerror(errno));
        exit(1);
        }

    memoriaC = mmap ( NULL, SM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, id_sharedMem1, 0 );
    if ( memoriaC == (void *) -1)
        {
        perror ( "mmap" );
        exit(1);
        }
    memoriaC->i=0;
    if (pthread_mutex_init(&(memoriaC->mutex), NULL)!=0)
            printf("mutex init 1 %s\n",strerror(errno));

    }else
        {

        if (pthread_mutex_init(&(memoriaC->mutex), NULL)!=0)
                printf("mutex init 2 %s\n",strerror(errno));

        }

    if(pthread_mutex_lock ( &(memoriaC->mutex))!=0)
            printf("mutex lock %s\n",strerror(errno));

    i = memoriaC->i + 1;
    memoriaC->i = i+loops;
    close ( id_sharedMem1 );
    for(j=0;j<loops;j++)
        i++;

    printf("i= %d\n",i);

    if(pthread_mutex_unlock ( &(memoriaC->mutex))!=0)
        printf("mutex unlock %s\n",strerror(errno));


//shm_unlink ( shared1_name );                      
}

【问题讨论】:

  • 发布的代码无法编译。它缺少 pthread 函数的标头。函数 ftruncate() 具有隐式声明。 ??函数关闭有隐式声明??未使用参数“argc”。顺便说一句:在引用任何命令行参数之前,应始终检查 argc 的值。如果不是所需数量的命令行参数,此检查也是输出“使用”消息的好时机
  • 我把代码改小了,把它放在这里,我忘记了那些标题。使用 sudo 运行并将 -lrt 放入编译中。即使没有这 2 个标头,代码也能完美编译。
  • 发布的代码缺少#include (对于Linux,对于其他操作系统可能不同。)。发布的代码缺少#include
  • 不,代码不能“完美”编译 建议编译时启用所有警告。 (对于 gcc,至少使用:'-Wall -Wextra -pedantic')然后修复警告。
  • 这些是 cmets,不是答案,请参阅下面的任何答案。发布“运行”(原文如此)代码时,要求是 1)编译,2)简短,3)显示问题。评论是一种建议改进代码和/或请求澄清的方式。答案是一种提示代码基本错误以及如何解决问题的方法。

标签: c mutex shared-memory


【解决方案1】:

要获得正确的共享内存互斥锁,需要一些“技巧”:

1) 您必须保证只有一个进程/线程创建/初始化互斥锁。如果您在创建共享内存时使用O_EXCL,则可以提高正确执行此操作的机会,然后让成功创建共享内存的进程负责初始化互斥锁。这本身可能是也可能不是一个足够的策略。

2) 您必须使用 pthread_mutexattr_setpshared` 和相关函数启用共享互斥锁。将互斥体放在共享内存中是不够的。

3) 您应该也了解pthread_mutexattr_settype,并知道何时以及为何使用不同的类型。

4) 您应该适当地使用pthread_mutexattr_setrobust,前提是您的操作系统支持它。否则,如果进程在持有锁的情况下退出,则会出现死锁。

【讨论】:

  • 当然,互斥锁不应该在共享内存中,因为共享内存是受互斥锁保护的资源。
  • 两个进程之间不共享的互斥锁究竟如何保护共享内存?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-10
  • 1970-01-01
  • 2021-08-19
  • 2015-10-06
  • 2021-10-10
  • 2012-06-29
  • 1970-01-01
相关资源
最近更新 更多