C信号量死锁
我为leetcode问题1116编写了以下代码。它应该打印出像01020304这样的东西。。。。然而,我的程序现在没有打印任何内容。我使用信号量信号发布和等待信号,并使用变量记录当前打印值C信号量死锁,c,multithreading,pthreads,semaphore,C,Multithreading,Pthreads,Semaphore,我为leetcode问题1116编写了以下代码。它应该打印出像01020304这样的东西。。。。然而,我的程序现在没有打印任何内容。我使用信号量信号发布和等待信号,并使用变量记录当前打印值 #include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <semaphore.h> typedef struct { int n; volatile int cu
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <semaphore.h>
typedef struct {
int n;
volatile int cur;
sem_t szero;
sem_t sodd;
sem_t sevn;
} ZeroEvenOdd;
ZeroEvenOdd* zeroEvenOddCreate(int n) {
ZeroEvenOdd* obj = (ZeroEvenOdd*) malloc(sizeof(ZeroEvenOdd));
obj->n = n;
obj->cur = 1;
sem_init(&obj->szero, 0, 1);
sem_init(&obj->sodd, 0, 0);
sem_init(&obj->sevn, 0, 0);
return obj;
}
// You may call global function `void printNumber(int x)`
// to output "x", where x is an integer.
void printNumber(int x) {
printf("%d", x);
}
void zero(ZeroEvenOdd* obj) {
while(obj->cur<obj->n) {
sem_wait(&obj->szero);
printNumber(0);
printNumber(obj->cur);
if (obj->cur%2==1) {
sem_post(&obj->sodd);
} else {
sem_post(&obj->sevn);
}
}
}
void even(ZeroEvenOdd* obj) {
while(obj->cur<=obj->n){
sem_wait(&obj->sevn);
printNumber(obj->cur);
obj->cur++;
sem_post(&obj->szero);
}
}
void odd(ZeroEvenOdd* obj) {
while(obj->cur<=obj->n) {
sem_wait(&obj->sodd);
printNumber(obj->cur);
obj->cur++;
sem_post(&obj->szero);
}
}
void zeroEvenOddFree(ZeroEvenOdd* obj) {
if(NULL!=obj) {
sem_destroy(&obj->szero);
sem_destroy(&obj->sodd);
sem_destroy(&obj->sevn);
free(obj);
}
}
int main() {
ZeroEvenOdd *f=zeroEvenOddCreate(5);
pthread_t tidz, tido, tide;
pthread_create(&tidz, NULL, (void *)&zero, (void *)f);
pthread_create(&tido, NULL, (void *)&odd, (void *)f);
pthread_create(&tide, NULL, (void *)&even, (void *)f);
pthread_join(tidz, NULL);
pthread_join(tido, NULL);
pthread_join(tide, NULL);
}
#包括
#包括
#包括
#包括
类型定义结构{
int n;
挥发性int-cur;
塞姆塞罗;
扫描电镜;
sem_t sevn;
}零偶奇数;
ZeroEvenOdd*zeroEvenOddCreate(整数n){
ZeroEvenOdd*obj=(ZeroEvenOdd*)malloc(sizeof(ZeroEvenOdd));
obj->n=n;
obj->cur=1;
sem_init(&obj->szero,0,1);
sem_init(&obj->sodd,0,0);
sem_init(&obj->sevn,0,0);
返回obj;
}
//您可以调用全局函数`void printNumber(int x)`
//输出“x”,其中x是一个整数。
无效打印编号(整数x){
printf(“%d”,x);
}
无效零(零偶数*obj){
while(obj->curn){
sem_wait(&obj->szero);
打印号码(0);
打印编号(obj->cur);
如果(对象->当前%2==1){
sem_post(&obj->sodd);
}否则{
sem_post(&obj->sevn);
}
}
}
空偶数(零偶数*obj){
while(obj->curn){
sem_wait(&obj->sevn);
打印编号(obj->cur);
obj->cur++;
sem_post(&obj->szero);
}
}
无效奇数(零偶数奇数*obj){
while(obj->curn){
sem_等待(&obj->sodd);
打印编号(obj->cur);
obj->cur++;
sem_post(&obj->szero);
}
}
void zeroEvenOddFree(ZeroEvenOdd*obj){
如果(NULL!=obj){
sem_销毁(&obj->szero);
sem_销毁(&obj->sodd);
sem_销毁(&obj->sevn);
免费(obj);
}
}
int main(){
ZeroEvenOdd*f=zeroEvenOddCreate(5);
pthread_t tidz,tido,tide;
pthread_创建(&tidz,NULL,(void*)&zero,(void*)f);
pthread_创建(&tido,NULL,(void*)和odd,(void*)f);
pthread_创建(&tide,NULL,(void*)和偶数,(void*)f);
pthread_join(tidz,NULL);
pthread_join(tido,NULL);
pthread_join(tide,NULL);
}
有什么问题?还有没有一种好方法可以使用GDB调试此类问题?逻辑:
cur n zero even odd
0 5 post(even) print,sleep -
1 5 post(odd) - print,sleep
2 5 post(even) print,sleep -
3 5 post(odd) - print,sleep
4 5 post(even) print,exit -
5 5 exit.
所以奇数仍然认为obj->cur==4[这就是它睡觉时的样子]。
有两个逻辑问题;对于线程程序,最好使用来自代码不同部分的printf()语句来跟踪执行流和变量值更改。对于从多个线程对对象进行非同步、非只读、非原子访问的未定义行为。
--- s.c 2020-12-10 14:27:25.518641527 +0000
+++ s2.c 2020-12-10 14:28:15.358562490 +0000
@@ -29,23 +29,27 @@
printf("%d", x);
}
+void sig(ZeroEvenOdd* obj) {
+ if (obj->cur%2==1) {
+ sem_post(&obj->sodd);
+ } else {
+ sem_post(&obj->sevn);
+ }
+}
+
void *zero(ZeroEvenOdd* obj) {
+ sem_wait(&obj->szero);
while(obj->cur<obj->n) {
- sem_wait(&obj->szero);
printNumber(0);
printNumber(obj->cur);
- if (obj->cur%2==1) {
- sem_post(&obj->sodd);
- } else {
- sem_post(&obj->sevn);
- }
+ sig(obj);
+ sem_wait(&obj->szero);
}
-
-
+ sig(obj);
}
void *even(ZeroEvenOdd* obj) {
- while(obj->cur<=obj->n){
+ while(obj->cur<obj->n){
sem_wait(&obj->sevn);
printNumber(obj->cur);
obj->cur++;
@@ -55,13 +59,13 @@
}
void *odd(ZeroEvenOdd* obj) {
- while(obj->cur<=obj->n) {
+ while(obj->cur<obj->n) {
sem_wait(&obj->sodd);
printNumber(obj->cur);
obj->cur++;
sem_post(&obj->szero);
}
-
+
}
void zeroEvenOddFree(ZeroEvenOdd* obj) {
@@ -84,5 +88,5 @@
pthread_join(tidz, NULL);
pthread_join(tido, NULL);
pthread_join(tide, NULL);
-
+ putchar('\n');
}