我用pthreads创建了一个C程序,它可以完美工作,直到添加任何形式的sleep函数,无论它是sleep()还是usleep()或nanosleep()。
是的,在您问之前,我知道usleep()已被弃用,并且我已从另一stackoferflow帖子中复制了nanosleep()的正确用法,但即使sleep()也不起作用。
代码(关键部分位于“客户”线程中的第99行):
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
#include <time.h>
#define LIBERA 0
#define OCCUPATA 1
#define TUTTE_SEDIE_OCCUPATE -1
#define OCCUPATA_DA_BARBIERE -2
#define NRCLIENTI 10
#define NRSEDIE 5
pthread_mutex_t poltrona_m, dorme_m, get_sedia_m, occupa_sedia_m;
sem_t sem;
int sedia_taglio = LIBERA, sedia_attesa[NRSEDIE];
void init_attr(void) {
int i;
for (i = 0; i < NRSEDIE; i++)
sedia_attesa[i] = LIBERA;
sem_init(&sem, 0, NRSEDIE);
pthread_mutex_unlock(&poltrona_m);
pthread_mutex_unlock(&dorme_m);
pthread_mutex_unlock(&get_sedia_m);
pthread_mutex_unlock(&occupa_sedia_m);
}
int my_sleep(long millis) {
struct timespec req, rem;
if (millis > 999) {
req.tv_sec = (int) (millis / 1000);
req.tv_nsec = (millis - ((long) req.tv_sec * 1000)) * 1000000;
} else {
req.tv_sec = 0;
req.tv_nsec = millis * 1000000;
}
return nanosleep(&req, &rem);
}
int get_sedia_libera() {
pthread_mutex_lock(&get_sedia_m);
int i;
for (i = 0; i < NRSEDIE; i++)
if (sedia_attesa[i] == LIBERA)
return i;
pthread_mutex_unlock(&get_sedia_m);
return TUTTE_SEDIE_OCCUPATE;
}
int occupa_sedia(int index) {
pthread_mutex_lock(&occupa_sedia_m);
int result;
if(sedia_attesa[index] == LIBERA){
sedia_attesa[index] = OCCUPATA;
result = 1;
}else
result = 0;
pthread_mutex_unlock(&occupa_sedia_m);
return result;
}
void libera_sedia(int index) {
sedia_attesa[index] = LIBERA;
}
void *barbiere(void *arg) {
while (1)
{
if (sedia_taglio == OCCUPATA) {
pthread_mutex_lock(&poltrona_m);
sedia_taglio = LIBERA;
pthread_mutex_unlock(&poltrona_m);
}
if (get_sedia_libera() == 0 && sedia_taglio == LIBERA) {
sedia_taglio = OCCUPATA_DA_BARBIERE;
pthread_mutex_lock(&dorme_m);
printf("[BARBIERE] il barbiere dorme...\n");
}
}
}
void *cliente(void *arg) {
int n;
int *id = (void *)arg;
while (1)
{
if (sedia_taglio == LIBERA || sedia_taglio == OCCUPATA_DA_BARBIERE) {
pthread_mutex_lock(&poltrona_m);
pthread_mutex_unlock(&dorme_m);
sedia_taglio = OCCUPATA;
printf("----[CLIENTE] Cliente \"%d\" si taglia i capelli!\n", *id);
my_sleep(2000);
sedia_taglio = LIBERA;
pthread_mutex_unlock(&poltrona_m);
pthread_exit(0);
} else {
n = get_sedia_libera();
if(n == TUTTE_SEDIE_OCCUPATE) {
fprintf(stderr, "----[CLIENTE] No posti liberi cliente \"%d\" lascia il negozio\n", *id);
pthread_exit((void *)1);
} else {
sem_wait(&sem);
n = get_sedia_libera();
if(occupa_sedia(n) && n != TUTTE_SEDIE_OCCUPATE){
printf("----[CLIENTE] Cliente \"%d\" aspetta su sedia #%d\n", *id, n+1);
while (sedia_taglio != LIBERA);
sem_post(&sem);
libera_sedia(n);
} else {
sem_post(&sem);
fprintf(stderr, "----[CLIENTE] No posti liberi cliente \"%d\" lascia il negozio\n", *id);
pthread_exit(0);
}
}
}
}
}
int main(int argc, char **argv) {
init_attr();
int i, id[NRCLIENTI];
pthread_t barbiere_thread, cliente_thread[NRCLIENTI];
if(pthread_create(&barbiere_thread, NULL, barbiere, NULL ) < 0){
fprintf(stderr, "[MAIN] Error creating \"barber\" thread!\n");
exit(EXIT_FAILURE);
}
printf("[MAIN] thread \"barber\" creato\n\n");
for (i = 0; i < NRCLIENTI; ++i) {
id[i] = i+1;
printf("[MAIN] thread \"client %d\" creato\n", id[i]);
if(pthread_create(&cliente_thread[i], NULL, cliente, &id[i]) < 0){
fprintf(stderr, "[MAIN] Error creating \"client %d\" thread!\n", id[i]);
exit(EXIT_FAILURE);
}
}
for (i = 0; i < NRCLIENTI; i++){
pthread_join(cliente_thread[i], NULL);
printf("[MAIN]Joined client \"%d\"\n", i+1);
}
//il programma non finira mai se sta ad aspettare un thread con un ciclo while(1) al suo interno
//senza condizioni di break!!!
pthread_join(barbiere_thread, NULL);
return 0;
}
正常执行(这是程序应该的工作方式:] >>
但是我不考虑usleep()因为 a)*不推荐使用,* b)您不能放置超过或等于100万微秒; usleep(1000000)无效[MAIN] thread "client 1" creato [BARBIERE] il barbiere dorme... hey [MAIN] thread "client 2" creato ----<<<<<<<<<<<<[CLIENTE] Cliente "1" si taglia i capelli! [MAIN] thread "client 3" creato ----<<<<<<<<<<<<[CLIENTE] Cliente "2" si taglia i capelli! [MAIN] thread "client 4" creato ----<<<<<<<<<<<<[CLIENTE] Cliente "3" si taglia i capelli! [MAIN] thread "client 5" creato ----<<<<<<<<<<<<[CLIENTE] Cliente "4" si taglia i capelli! [MAIN] thread "client 6" creato ----<<<<<<<<<<<<[CLIENTE] Cliente "5" si taglia i capelli! [MAIN] thread "client 7" creato ----<<<<<<<<<<<<[CLIENTE] Cliente "6" si taglia i capelli! [MAIN] thread "client 8" creato ----<<<<<<<<<<<<[CLIENTE] Cliente "7" si taglia i capelli! [MAIN] thread "client 9" creato ----<<<<<<<<<<<<[CLIENTE] Cliente "8" si taglia i capelli! [MAIN] thread "client 10" creato ----<<<<<<<<<<<<[CLIENTE] Cliente "9" si taglia i capelli! ----<<<<<<<<<<<<[CLIENTE] Cliente "10" si taglia i capelli! [MAIN]Joined client "1" [MAIN]Joined client "2" [MAIN]Joined client "3" [MAIN]Joined client "4" [MAIN]Joined client "5" [MAIN]Joined client "6" [MAIN]Joined client "7" [MAIN]Joined client "8" [MAIN]Joined client "9" [MAIN]Joined client "10"
执行任何睡眠方法,sleep(1),具有1秒或100k微秒usleep()的nanosleep()
最奇怪的是,如果我使用MinGW在Windows IntelliJ Clion中运行此命令,则sleep()函数似乎被完全忽略了(程序在不到一秒钟的时间内执行完毕)![MAIN] thread "client 1" creato [BARBIERE] il barbiere dorme... [MAIN] thread "client 2" creato ----[CLIENTE] Cliente "1" si taglia i capelli! [MAIN] thread "client 3" creato [MAIN] thread "client 4" creato [MAIN] thread "client 5" creato [MAIN] thread "client 6" creato [MAIN] thread "client 7" creato [MAIN] thread "client 8" creato [MAIN] thread "client 9" creato [MAIN] thread "client 10" creato [MAIN]Joined client "1"
如您所见,线程只是...停顿。我等了终端打开了5分钟,但仍然没有任何变化。
感谢您通读所有这些内容,希望我们能找到解决方案,对于获得的任何帮助,我将不胜感激!
我创建了一个带有pthreads的C程序,它可以完美工作,直到添加任何形式的sleep函数,无论它是sleep()还是usleep()或nanosleep()。是的,在您问之前,我知道usleep()是...
使用几个嵌套的mutexes