【问题标题】:sem_init and pthread_mutex_initsem_init 和 pthread_mutex_init
【发布时间】:2020-03-05 11:37:17
【问题描述】:

我正在编写 2 个类似的代码,用于使用互斥锁和信号量从给定的数字集中打印奇数和偶数。这两个代码都可以正常工作。

但是,在使用互斥锁时,即使我不声明pthread_mutex_init 函数,程序仍然可以毫无问题地执行。但信号量并非如此。对于这种情况,我必须在 main() 中声明sem_init,否则程序执行会卡在sem_wait()(调试后发现)。

那么,在互斥锁的情况下,即使没有声明init(),程序如何执行?

作为参考,我附上信号量代码。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>

sem_t mutex;
pthread_t tid[2];
unsigned int shared_data[] = {23,45,67,44,56,78,91,102};
unsigned int rc;
int len=(sizeof(shared_data)/sizeof(shared_data[0]));
int i=0;

void *even(void *arg) {
    rc = sem_wait(&mutex);
    int temp = rc;
    if(rc)
        printf("Semaphore failed\n");

    do{
        if(shared_data[i] %2 == 0) {
            printf("Even: %d\n",shared_data[i]);
            i++;
        }
        else
            rc = sem_post(&mutex);
    }while(i<len);
}

void *odd(void *arg) {
    rc = sem_wait(&mutex);
    if(rc)
        printf("Semaphore failed\n");

    do {
        if(shared_data[i] %2 != 0) {
            printf("Odd: %d\n",shared_data[i]);
            i++;
        }
        else
            rc = sem_post(&mutex);
    }while(i<len);
}

int main() {
    sem_init(&mutex, 0,1);
    pthread_create(&tid[0], 0, &even, 0);
    pthread_create(&tid[1], 0, &odd, 0);

    pthread_join(tid[0],NULL);
    pthread_join(tid[1],NULL);

    sem_destroy(&mutex);

    return 0;
}

编辑:同时附加互斥锁代码。

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>

pthread_t tid[2];
unsigned int shared_data []= {23,45,67,44,56,78,91,102};
pthread_mutex_t mutex;
unsigned int rc;
int len=(sizeof(shared_data)/sizeof(shared_data[0]));
int i=0;

void* PrintEvenNos(void *ptr)
{
    rc = pthread_mutex_lock(&mutex);
    if(rc)
        printf("Mutex lock has failed\n");
    do
    {
       if(shared_data[i]%2 == 0)
       {
         printf("Even:%d\n",shared_data[i]);
         i++;
       } else {
          rc=pthread_mutex_unlock(&mutex);
       }
    } while(i<len);
}

void* PrintOddNos(void* ptr1)
{
    rc = pthread_mutex_lock(&mutex);
    if(rc)
        printf("Mutex lock has failed\n");
    do
    {
       if(shared_data[i]%2 != 0)
       {
         printf("Odd:%d\n",shared_data[i]);
         i++;
       } else {
          rc=pthread_mutex_unlock(&mutex);
       }
    } while(i<len);
}

void main(void)
{   
    pthread_create(&tid[0],0,PrintEvenNos,0);
    pthread_create(&tid[1],0,PrintOddNos,0);

    pthread_join(tid[0],NULL);
    pthread_join(tid[1],NULL);
}

【问题讨论】:

  • 因为您的变量都是全局变量,所以它们将被零初始化。对于pthread_mutex_t,这可能恰好是您本地系统上的正确方式,但对于sem_t 则不然。一般来说,总是明确地“初始化”你的变量,不管是全局的还是非全局的。
  • @attyman17 使用pthread_mutex_init 的代码在哪里让你惊讶?
  • @Landstalker 我已经添加了。
  • @battyman17 之所以起作用,是因为编译器分配的初始化值与您使用 pthread_mutex_init 函数显式分配的值一致。
  • @SolomonSlow 程序不再需要显式初始化静态分配的pthread_mutex_t 对象。???在哪里?每POSIX pthread_mutex_init():“在默认互斥属性合适的情况下,宏PTHREAD_MUTEX_INITIALIZER可用于初始化互斥锁。效果应等同于通过调用pthread_mutex_init()动态初始化,参数attr指定为NULL ,但不执行错误检查。”

标签: c multithreading mutex semaphore


【解决方案1】:

那么,在互斥锁的情况下,即使没有声明init(),程序如何执行?

这是undefined behavior,所以没有正确的结果。 Per POSIX pthread_mutex_lock():

如果mutex 不引用已初始化的互斥对象,则pthread_mutex_lock()pthread_mutex_trylock()pthread_mutex_unlock() 的行为未定义。

“似乎可以工作”是未定义行为的一种可能结果。

【讨论】:

    【解决方案2】:

    您有sem_init 呼叫sem_t mutex;

    但是pthread_mutex_init 缺少pthread_mutex_t mutex; 的调用。

    【讨论】:

    • 他很惊讶即使没有pthread_mutex_init,他的程序也能正常工作。编译器为他做了这个任务......编译器的隐式初始化与使用pthread_mutex_init的显式初始化相吻合
    【解决方案3】:

    两个代码都可以正常工作。

    不,他们没有;但首先:

    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    

    你应该如何初始化你的互斥锁。在您的系统上,此值可能为零,这将等同于您所拥有的。不管怎样,问题是你的程序坏了。

    您的一个线程(偶数、奇数)获得了锁。在偶数的情况下,当 i 为 0、1、2、5 或 6 时;你解锁它,这将允许odd() 继续。在奇数的情况下,当 i 是 3、4、5 或 7 时,您解锁它,这将允许 even() 继续。所以在你的逻辑中,锁什么都不做。

    此外,信号量是计数器;所以当你释放它 5 次时,你允许接下来的 5 sem_waits 继续。简单的互斥锁是门,所以只有第一个解锁有任何效果,后面的 4 个是错误的。您不检查解锁的错误状态,这通常是发现逻辑错误的错误状态。

    fwiw,在 macos 上,pthread_mutex_lock() 都报错了。

    【讨论】:

      猜你喜欢
      • 2012-07-24
      • 2011-03-11
      • 2012-12-28
      • 2011-12-13
      • 2010-11-27
      • 1970-01-01
      • 1970-01-01
      • 2021-06-09
      相关资源
      最近更新 更多