/* System V Semaphores and pthreads. */ #include #include #include #include #include #include #include #include #include "nya/array.h" #define massert( cond, msg ) \ if( cond ) { \ perror( msg ); \ exit(-1); \ } #define set_semop_( _sem, _op, _num ) \ _sem.sem_num = _num; \ _sem.sem_op = _op; \ _sem.sem_flg = SEM_UNDO; \ #define PATH "/tmp/tmp_191944_s/d" char buf[] = "abcdefghijklmnopqrstuvwsyz"; int sem_id = 0; struct sembuf lock_m, unlock_m, lock_i, unlock_i, lock_r, unlock_r; void clear_sem( ) { massert( semctl( sem_id, 0, IPC_RMID, 0) == -1, "semctl"); exit(0); } void *inv( ) { int len = strlen(buf); while( 1 ) { massert( semop( sem_id, &lock_i, 1) < 0, "semop"); inverse(buf, len); massert( semop( sem_id, &unlock_m, 1) < 0, "semop"); } } void *rev( ) { int len = strlen(buf); while( 1 ) { massert( semop( sem_id, &lock_r, 1) < 0, "semop"); reverse(buf, len); massert( semop( sem_id, &unlock_m, 1) < 0, "semop"); } } int main( int argc, char* argv[] ) { pthread_t inv_pthread, rev_pthread; key_t key; struct sembuf lock, unlock ; set_semop_( lock_m, -1, 0); set_semop_( unlock_m, 1, 0); set_semop_( lock_i, -1, 1); set_semop_( unlock_i, 1, 1); set_semop_( lock_r, -1, 2); set_semop_( unlock_r, 1, 2); massert((key = ftok( PATH, 'd' )) < 0, "ftok" ); massert((sem_id = semget(key, 3, 0666|IPC_CREAT )) < 0, "semget"); massert(pthread_create( &inv_pthread, NULL, inv, NULL ) != 0, "pthread" ); massert(pthread_create( &rev_pthread, NULL, rev, NULL ) != 0, "pthread" ); signal( SIGINT, clear_sem ); while(1) { massert( semop( sem_id, &unlock_i, 1) < 0, "semop"); massert( semop( sem_id, &lock_m, 1) < 0, "semop"); puts(buf); sleep( 1 ); massert( semop( sem_id, &unlock_r, 1) < 0, "semop"); massert( semop( sem_id, &lock_m, 1) < 0, "semop"); puts(buf); sleep( 1 ); } return 0; }