C sem_init和pthread_mutex_init

C sem_init和pthread_mutex_init,c,multithreading,mutex,semaphore,C,Multithreading,Mutex,Semaphore,我正在编写两个类似的代码,用于使用互斥锁和信号量从给定的数字集中打印奇数和偶数。这两种代码都可以正常工作 但是,在使用互斥锁时,即使我不声明pthread\u mutex\u init函数,程序仍然可以正常执行。但信号量不是这样的。对于这种情况,我必须在main()中声明sem_init,否则程序执行会卡在sem_wait()(在调试后找到) 那么,在互斥锁的情况下,即使没有声明init(),程序如何执行呢 作为参考,我附加了信号灯代码 #include <stdio.h> #inc

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

但是,在使用互斥锁时,即使我不声明
pthread\u mutex\u 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;
}
#包括
#包括
#包括
#包括
sem_t互斥体;
pthread_t tid[2];
无符号整数共享_数据[]={23,45,67,44,56,78,91102};
无符号整数rc;
int len=(sizeof(共享_数据)/sizeof(共享_数据[0]);
int i=0;
空*偶(空*参数){
rc=sem_等待(&mutex);
内部温度=rc;
if(rc)
printf(“信号量失败\n”);
做{
if(共享_数据[i]%2==0){
printf(“偶数:%d\n”,共享_数据[i]);
i++;
}
其他的
rc=sem_post(&mutex);

}而(i您有
sem\u init
调用
sem\u t mutex;


但是
pthread\u mutex\u init的
pthread\u mutex\u t mutex;

缺少
sem\u init
调用
sem\u mutex;

但是
pthread\u mutex\u mutex;
pthread\u mutex\u init调用缺失

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

这是错误的,因此没有正确的结果:

如果
mutex
未引用初始化的互斥对象,则
pthread\u mutex\u lock()
pthread\u mutex\u trylock()
pthread\u mutex\u unlock()
的行为未定义

“似乎有效”是未定义行为的一种可能结果

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

这是错误的,因此没有正确的结果:

如果
mutex
未引用初始化的互斥对象,则
pthread\u mutex\u lock()
pthread\u mutex\u trylock()
pthread\u mutex\u unlock()
的行为未定义

“似乎有效”是未定义行为的一种可能结果

这两种代码都可以正常工作

不,他们没有;但首先:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
是您应该初始化互斥锁的方式。在您的系统上,此值可能为零,这将等同于您的值。无论哪种方式,问题是您的程序已损坏

你的一个线程(偶数,奇数)获得一个锁。在偶数的情况下,当我是0,1,2,5或6时,你解锁它,这将允许奇数()继续。在奇数的情况下,当我是3,4,5或7时,你解锁它,这将允许偶数()继续。因此在你的逻辑中,锁根本不起任何作用

此外,信号量是计数器;因此,当您释放它5次时,您将允许接下来的5次sem_等待继续。简单的互斥锁是门,因此只有第一次解锁有效,随后的4次是错误。您不检查解锁的错误状态,通常是发现逻辑错误的状态

fwiw,在macos上,pthread_mutex_lock()都报告了一个错误

这两种代码都可以正常工作

不,他们没有;但首先:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
是您应该初始化互斥锁的方式。在您的系统上,此值可能为零,这将等同于您的值。无论哪种方式,问题是您的程序已损坏

你的一个线程(偶数,奇数)获得一个锁。在偶数的情况下,当我是0,1,2,5或6时,你解锁它,这将允许奇数()继续。在奇数的情况下,当我是3,4,5或7时,你解锁它,这将允许偶数()继续。因此在你的逻辑中,锁根本不起任何作用

此外,信号量是计数器;因此,当您释放它5次时,您将允许接下来的5次sem_等待继续。简单的互斥锁是门,因此只有第一次解锁有效,随后的4次是错误。您不检查解锁的错误状态,通常是发现逻辑错误的状态


fwiw,在macos上,pthread_mutex_lock()都报告了一个错误。

因为您的变量都是全局变量,它们将被零初始化。对于
pthread_mutex_t
来说,这可能恰好是本地系统上的正确方式,但对于
sem_t
来说则不是。通常,总是显式地“初始化”您的变量是全局变量还是非全局变量。@attyman17使用
pthread\u mutex\u init的代码在哪里?@landstapper我现在已经添加了它。@battyman17它工作只是因为初始化值​​编译器指定的值与值一致​​您将使用pthread\u mutex\u init函数显式分配的对象。@SolomonSlow程序不再需要显式初始化静态分配的
pthread\u mutex\t
对象。??其中?根据:“在默认互斥体属性合适的情况下,可以使用宏
PTHREAD\u mutex\u初始值设定项
初始化互斥体。其效果相当于通过调用
PTHREAD\u mutex\u init()
进行动态初始化,参数attr指定为
NULL
,但不执行错误检查。因为您的变量都是全局变量,所以它们将被零初始化。对于
pthread\u mutex\t
,这可能恰好是本地系统上的正确方式,但对于
sem\u t
。通常,总是显式地“初始化”您的变量是全局变量还是非全局变量。@attyman17使用
pthread\u mutex\u init的代码在哪里?@landstapper我现在已经添加了它。@battyman17它工作只是因为初始化值​​编译器指定的值与值一致​​您应该使用pthread_mut显式分配的