sem_init 和 pthread_mutex_init
sem_init and pthread_mutex_init
我正在编写 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);
}
您有 sem_init
个要求 sem_t mutex;
。
但是 pthread_mutex_init
缺少 pthread_mutex_t mutex;
的调用。
So, how in the case of mutex lock, even without declaring init(), the program executes?
这是undefined behavior, so there is no proper result. Per POSIX pthread_mutex_lock()
:
If mutex
does not refer to an initialized mutex object, the behavior of pthread_mutex_lock()
, pthread_mutex_trylock()
, and pthread_mutex_unlock()
is undefined.
"Appears to work" 是未定义行为的一种可能结果。
Both of the codes works fine.
不,他们没有;但首先:
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() 都报告错误。
我正在编写 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);
}
您有 sem_init
个要求 sem_t mutex;
。
但是 pthread_mutex_init
缺少 pthread_mutex_t mutex;
的调用。
So, how in the case of mutex lock, even without declaring init(), the program executes?
这是undefined behavior, so there is no proper result. Per POSIX pthread_mutex_lock()
:
If
mutex
does not refer to an initialized mutex object, the behavior ofpthread_mutex_lock()
,pthread_mutex_trylock()
, andpthread_mutex_unlock()
is undefined.
"Appears to work" 是未定义行为的一种可能结果。
Both of the codes works fine.
不,他们没有;但首先:
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() 都报告错误。