Newsgroup: it.comp.os.linux.development
Titolo: utilizzo di semop

 (gdb)
Il propblema fondamentalmente e' che non so come interpretare l'errore,
e quindi nemmeno come correggerlo.
Qualcuno mi puo' aiutare?
Grazie, Paolo
Per compilare uso
g++ -g -lpthread semop.cc
con il gcc 3.3.5
e questo e' il codice del programa
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/sem.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <cassert>
using namespace std;
void *conta( void *ptr1 );
void *stampa( void *ptr2 );
int semid1, semid2;
struct sembuf s_wait,s_post;
main()
{
     pthread_t thread1, thread2;
     int  iret1, iret2;
     int i;
     //creo i semafori
     semid1 = semget(1234, 1, 0666 | IPC_CREAT);
     semid2 = semget(5678, 1, 0666 | IPC_CREAT);
     //preparo le strutture di tipo sembuf per eseguire l'equivalente
di una wait e di una post
     s_wait.sem_num = 0;
     s_wait.sem_op = -1;
     s_wait.sem_flg = 0;
     s_post.sem_num = 0;
     s_post.sem_op = +1;
     s_post.sem_flg = 0;
     //metto il valore iniziale del semaforo semid1 a 1
    if (semctl(semid1, 0, SETVAL, 1) == -1) {
    	perror("main: semctl");
    	exit(1);
    };
    //metto il valore iniziale del semaforo semid2 a 0
    if (semctl(semid2, 0, SETVAL, 0) == -1) {
    	perror("main: semctl");
    	exit(1);
    };
    //creo le thread
     iret1 = pthread_create( &thread1, NULL, conta, (void*) &i);
     iret2 = pthread_create( &thread2, NULL, stampa, (void*) &i);
     pthread_join( thread1, NULL);
     pthread_join( thread2, NULL);
     printf("Thread 1 returns: %d\n",iret1);
     printf("Thread 2 returns: %d\n",iret2);
     //distruggo i semafori
    if (semctl(semid1, 0, IPC_RMID, 1) == -1) {
    	perror("main: semctl");
    	exit(1);
    };
    if (semctl(semid2, 0, IPC_RMID, 1) == -1) {
    	perror("main: semctl");
    	exit(1);
    };
     exit(0);
}
void *conta( void *ptr1 ){
	int *addr = (int *)ptr1;
	int k=0;
	while(k<1000){
		if (semop(semid1,&s_wait,1) == -1) {
            		perror("conta wait => IPC error: semop"); exit(1);
        	};
		k++;
		*addr = k;
		printf("k=%d\n",k);
		if(semop(semid2,&s_post,1) == -1){
			perror("conta post => IPC error: semop"); exit(1);
		};
	};
};
void *stampa( void *ptr2 ){
	int *addr = (int *)ptr2;
	int k;
	while(k<1000){
		if(semop(semid2,&s_wait,1) == -1){
			perror("stampa wait => IPC error: semop"); exit(1);
		};
		k = *addr;
		printf("dato=%d\n",k);
		if(semop(semid1,&s_post,1) == -1){
			perror("stampa post => IPC error: semop"); exit(1);
		};
	};
};

> conta wait => IPC error: semop: Interrupted system call
EINTR vuol dire che al processo è arrivato un segnale e la syscall è
stata interrotta. In questo caso il segnale è probabilmente uno di
quelli che il gdb usa per il debug.
I semafori SYSV, comunque, sono indicati per sincronizzazione
inter-processo, se devi sincronizzare dei thread puoi usare delle mutex
(pthread_mutex_t) unitamente alle condition (pthread_cond_t)
pthread_cond_t notempty = PTHREAD_COND_INITIALIZER;
pthread_cond_t notfull = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
/* producer */
pthread_mutex_lock(&lock);
if (buffer_full)
        /* Aspetto un posto nel buffer */
        pthread_cond_wait(&notfull, &lock);
/* Inserisco un elemento nel buffer */
fill_buffer();
/* Segnalo la presenza di elemento nuovo */
pthread_cond_signal(&notempty);
pthread_mutex_unlock(&lock);
/* consumer */
pthread_mutex_lock(&lock);
if (buffer_empty)
        /* Aspetto un nuovo elemento */
        thread_cond_wait(&notempty, &lock);
/* Consumo un elemento */
consume_buffer();
pthread_cond_signal(&notfull);
pthread_mutex_unlock(&lock);
Luca
-- 
Home: 
http://kronoz.cjb.net
Il dottore mi ha detto di smettere di fare cene intime per quattro.
A meno che non ci siamo altre tre persone.

 quelli che il gdb usa per il debug.
In effetti, continuando a cercare nei NG sembra proprio che l'errore
sia causato dalle continue SIGSTOP di gdb. Al momento ho risolto
implementando le semop con variabili condizionali e mutex, pero' la
domanda che resta in sospeso e': come si fa ad utilizzare gdb per un
programma in cui ci sono delle SEMOP?
Possibile che nessuno abbia risolto il problema?
Paolo