/* * Class: sharedmemory_SharedMemory * Method: close_sem * Signature: (Ljava/lang/String;)I */ JNIEXPORT jint JNICALL Java_sharedmemory_SharedMemory_close_1sem (JNIEnv *env, jobject obj, jstring descriptor) { jint ret = -1; const char* desc = (*env)->GetStringUTFChars( env, descriptor , NULL ) ; ret = close_sem(desc); (*env)->ReleaseStringUTFChars(env, descriptor ,desc); return ret; }
int main(int argc, char ** argv){ key_t key; int *shm_seg, shm_id, sem_id, pid, fd_fifo; int i, tmp, count_r; int r_arr[2]; unsigned int nn, n, size; struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = sigchldhandler; if (sigaction(SIGCHLD, &sa, 0) < 0){ perror("sigaction"); exit(0); } printf("n: "); scanf("%u", &n); if (n < 2){ printf("n must be bigger than 1\n"); exit(0); } nn = 2; while (nn < n){ nn <<= 1; } /*-initialize*/ if (mknod(FIFO, S_IFIFO | 0660, 0) < 0){ perror("mknod: "); exit(2); } if ((key = ftok(argv[0], 'q')) < 0) { perror("ftok"); exit(2); }/*========================================================================*/ size = nn*sizeof(int); if ((shm_id = open_seg(key,size)) < 0){ printf("open_seg error\n"); exit(2); } if (*(shm_seg = shmat(shm_id, 0, 0)) < 0) { printf("error attaching %d\n",shm_id); exit(2); } if ((sem_id = open_sem(key,4)) < 0){ printf("open_sem error\n"); exit(2); } srand(key); for(i = 0; i < n; i++){ shm_seg[i] = rand() % 100; printf("%d ", shm_seg[i]); } for(; i < nn; i++){ shm_seg[i] = 100; printf("%d ", 100); } printf("\n"); /*=initialize*/ op_sem(sem_id, &r_unlock[0]); op_sem(sem_id, &w_unlock[0]); for(i = 0; i < nn/2; i++){ if ((pid = fork()) < 0){ printf("fork %d", i); exit(0); } if (pid == 0){ if ((fd_fifo = open(FIFO, O_RDONLY | O_NONBLOCK)) < 0){ if (errno == EINTR){ _exit(0); } perror("open2: "); _exit(2); } while (get_sem_val(sem_id, 3) > 0){ r_arr[0] = 0; r_arr[1] = 0; /* trouble: В конце работы read читает из пустой фифо. Надо найти макс задержку read'а. Или семафоры...:( */ op_sem(sem_id, &r_lock[0]); if ((count_r = read(fd_fifo, &r_arr, sizeof(int)*2)) < 0){ if (errno == EAGAIN){ continue; } perror("read: "); _exit(2); }; if (count_r < 2){ continue; } op_sem(sem_id, &iter_unlock[0]); op_sem(sem_id, &r_unlock[0]); if (shm_seg[r_arr[0]] > shm_seg[r_arr[1]]){ tmp = shm_seg[r_arr[0]]; op_sem(sem_id, &w_lock[0]); shm_seg[r_arr[0]] = shm_seg[r_arr[1]]; shm_seg[r_arr[1]] = tmp; op_sem(sem_id, &w_unlock[0]); } } printf("die.\n"); if (close(fd_fifo) < 0){ perror("close2"); } _exit(0); } } while (1){ if ((fd_fifo = open(FIFO, O_WRONLY | O_NONBLOCK)) < 0){ if (errno == EINTR || errno == ENXIO){ continue; } perror("open3: "); exit(0); }else{ break; } } op_sem(sem_id, &work_start[0]); make_mn(nn, nn, 1, fd_fifo, sem_id); op_sem(sem_id, &work_stop[0]); if (close(fd_fifo) < 0){ perror("close2"); }; for(i = 0; i < n; i++){ printf("%d ", shm_seg[i]); } printf("\n"); while(die < nn/2); detach_seg((char *)shm_seg); close_seg(shm_id); close_sem(sem_id); return 0; }