2016-12-14 2 views
1

Я новичок в C, и я просто пытаюсь запустить этот фрагмент кода книги Пачеко «Введение в параллельное программирование». И я просто не могу понять, как реализовать инициализацию семафоров в main(). Есть &semaphores[dest] и &semaphores[my_rank] массивы?Управление порядком нитей с помощью семафоров в C

код C:

/* messages is allocated and initialized to NULL in main */ 
/* semaphores is allocated and initialized to 0 (locked) in main */ 
void *Send_msg(void* rank) { 
    long my_rank = (long) rank; 
    long dest = (my_rank + 1) % thread_count; 
    char* my_msg = (char*)malloc(MSG_MAX*sizeof(char)); 

    sprintf(my_msg, "Hello to %ld from %ld", dest, my_rank); 
    messages[dest] = my_msg; 
    sem_post(&semaphores[dest]) 
    /* ‘‘Unlock’’ the semaphore of dest */ 

    sem_wait(&semaphores[my_rank]);/* Wait for our semaphore to be unlocked */ 
    printf("Thread %ld > %s\n", my_rank, messages[my_rank]); 

    return NULL; 
} /* Send_msg */ 

Я хочу реализовать этот тип механизма заказа, как я пытаюсь написать выходной массив в файл. Вот мой код:

int k = 0; 
long dest = (my_rank + 1) % THREAD_COUNT; 

if(genCount%50==0){ 
//incrementing file name 

//semapthore lock 
sem_post(&semaphores[dest]); 

sem_wait(&semaphores[my_rank]); 

snprintf(buffer, sizeof(char) * 32, "file%i.dat", k); 

//open the file 
fp = fopen(buffer, "r+"); 
if (fp == NULL) { 
    printf("I couldn't open file for writing.\n"); 
    exit(0); 
} 

int loop1, loop2; 

//outputting the array into the file 
for (loop1 = my_first_i; loop1 < my_last_i; loop1++){ 
    for(loop2 = my_first_i; loop2 < my_last_i; loop2++){ 
fprintf(fp,"%d\t", map[loop1][loop2]); 
    } 
} 

//close the file 
fclose(fp); 

k++; 

}

Инициализация semaphors в main():

int semCount; 
    for(semCount = 0; semCount < THREAD_COUNT; semCount++){ 
    sem_init(&semaphores[semCount], 0, 1); 
    } 

У меня также есть его в качестве глобальной переменной:

#define THREAD_COUNT 4 
sem_t semaphores[THREAD_COUNT]; 

Программа компилирует, но он дает мне эту ошибку:

 *** Error in `./ebola_serial': double free or corruption (out): 0x00007f49700008c0 *** 
    *** Error in `======= Backtrace: ========= 
    /lib64/libc.so.6(+0x7238e)[0x7f49868f038e] 
    ./ebola_serial/lib64/libc.so.6(+0x7a0c8)[0x7f49868f80c8] 
    ': /lib64/libc.so.6(cfree+0x48)[0x7f49868fb798] 
    double free or corruption (out)/lib64/libc.so.6(fclose+0x113)[0x7f49868e6473] 
    ./ebola_serial[0x401717] 
    /lib64/libpthread.so.0(+0x75bd)[0x7f4986c395bd] 
    : 0x/lib64/libc.so.6(clone+0x6d)[0x7f498697562d] 
    ======= Memory map: ======== 
    00007f49700008c000400000-00402000 r-xp 00000000 08:01 802698        /home/name/Desktop/try ca/ebola_serial 
    00601000-00602000 r--p 00001000 08:01 802698        /home/name/Desktop/try ca/ebola_serial 
    00602000-00603000 rw-p 00002000 08:01 802698        /home/name/Desktop/try ca/ebola_serial 
    00603000-009d3000 rw-p 00000000 00:00 0 
    01b96000-01bb7000 rw-p 00000000 00:00 0         [heap] 
    7f4970000000-7f4970021000 rw-p 00000000 00:00 0 
    7f4970021000-7f4974000000 ---p 00000000 00:00 0 
    7f4978000000-7f4978021000 rw-p 00000000 00:00 0 
    7f4978021000-7f497c000000 ---p 00000000 00:00 0 
    7f497c000000-7f497c021000 rw-p 00000000 00:00 0 
    7f497c021000-7f4980000000 ---p 00000000 00:00 0 
    7f4980000000-7f4980021000 rw-p 00000000 00:00 0 
    7f4980021000-7f4984000000 ---p 00000000 00:00 0 
    7f4984663000-7f4984679000 r-xp 00000000 08:01 131531      /usr/lib64/libgcc_s-4.9.2.so.1 
    7f4984679000-7f4984878000 ---p 00016000 08:01 131531      /usr/lib64/libgcc_s-4.9.2.so.1 
    7f4984878000-7f4984879000 r--p 00015000 08:01 131531      /usr/lib64/libgcc_s-4.9.2.so.1 
    7f4984879000-7f498487a000 rw-p 00016000 08:01 131531      /usr/lib64/libgcc_s-4.9.2.so.1 
    7f498487a000-7f498487b000 ---p 00000000 00:00 0 
    7f498487b000-7f498507b000 rw-p 00000000 00:00 0       [stack:7376] 
    7f498507b000-7f498507c000 ---p 00000000 00:00 0 
    7f498507c000-7f498587c000 rw-p 00000000 00:00 0 
    7f498587c000-7f498587d000 ---p 00000000 00:00 0 
    7f498587d000-7f498607d000 rw-p 00000000 00:00 0       [stack:7374] 
    7f498607d000-7f498607e000 ---p 00000000 00:00 0 
    7f498607e000-7f498687e000 rw-p 00000000 00:00 0       [stack:7373] 
    7f498687e000-7f4986a28000 r-xp 00000000 08:01 130947      /usr/lib64/libc-2.20.so 
    7f4986a28000-7f4986c28000 ---p 001aa000 08:01 130947      /usr/lib64/libc-2.20.so 
    7f4986c28000-7f4986c2c000 r--p 001aa000 08:01 130947      /usr/lib64/libc-2.20.so 
    7f4986c2c000-7f4986c2e000 rw-p 001ae000 08:01 130947      /usr/lib64/libc-2.20.so 
    7f4986c2e000-7f4986c32000 rw-p 00000000 00:00 0 
    7f4986c32000-7f4986c49000 r-xp 00000000 08:01 130973      /usr/lib64/libpthread-2.20.so 
    7f4986c49000-7f4986e48000 ---p 00017000 08:01 130973      /usr/lib64/libpthread-2.20.so 
    7f4986e48000-7f4986e49000 r--p 00016000 08:01 130973      /usr/lib64/libpthread-2.20.so 
    7f4986e49000-7f4986e4a000 rw-p 00017000 08:01 130973      /usr/lib64/libpthread-2.20.so 
    7f4986e4a000-7f4986e4e000 rw-p 00000000 00:00 0 
    7f4986e4e000-7f4986f53000 r-xp 00000000 08:01 130955      /usr/lib64/libm-2.20.so 
    7f4986f53000-7f4987152000 ---p 00105000 08:01 130955      /usr/lib64/libm-2.20.so 
    7f4987152000-7f4987153000 r--p 00104000 08:01 130955      /usr/lib64/libm-2.20.so 
    7f4987153000-7f4987154000 rw-p 00105000 08:01 130955      /usr/lib64/libm-2.20.so 
    7f4987154000-7f4987174000 r-xp 00000000 08:01 130940      /usr/lib64/ld-2.20.so 
    7f4987353000-7f4987356000 rw-p 00000000 00:00 0 
    7f498736d000-7f4987373000 rw-p 00000000 00:00 0 
    7f4987373000-7f4987374000 r--p 0001f000 08:01 130940      /usr/lib64/ld-2.20.so 
    7f4987374000-7f4987376000 rw-p 00020000 08:01 130940      /usr/lib64/ld-2.20.so 
    7ffce31e3000-7ffce3205000 rw-p 00000000 00:00 0       [stack] 
    7ffce320d000-7ffce320f000 r--p 00000000 00:00 0       [vvar] 
    7ffce320f000-7ffce3211000 r-xp 00000000 00:00 0       [vdso] 
    ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0     [vsyscall] 
    Aborted 

Любая помощь будет оценена по достоинству.

+0

Прочтите 'man sem_init' и спросите далее. – user902384

+2

Что это такое C? Кажется, что '//' становится '/' и '_' отсутствуют ... В любом случае' [] 'является оператором индекса массива, чтобы ответить на ваш вопрос. –

+1

Это плохая копия из какой-либо книги или сканирования. Вы замечаете unlockquotes. Это печатные кавычки, а не кодовые цитаты моноширинного шрифта. Подчеркивает недостатки. OCR имеет неудачную реализацию. – user902384

ответ

1

выглядит как семафоры, определенных таким образом

sem_t semaphores[N]; 

где N является количеством семафоров

Для инициализации семафора вы должны использовать sem_init функции, которая принимает указатель на нужный семафор, флаг, который позволяет совместно процесс использование и начальное значение семафора.

sem_init(&semaphores[0], 0, 1); 

В вашем случае семафоров экземпляры, хранящиеся в массиве называется семафоров, так что вы должны перебирать всех членов массива для инициализации

int i; 
for(i=0;i<N;i++) 
    sem_init(&semaphores[i], 0, 1); 

Finlay для использования семафоров вы должны вызвать sem_wait и sem_post функции таким образом

sem_wait(&semaphores[0 to N-1]); // Locking semaphore 
sem_post(&semaphores[0 to N-1]); // Unlocking it 
+0

О, ладно, я понимаю. Значит ли это, что у меня должен быть один семафор для каждого потока? –

+1

Семафоры используются для защиты данных в критических разделах, например, рассматривают проблему производителя-потребителя, один поток создает некоторые данные, а потребительские потоки их потребляют, теперь рассмотрим, что два потока имеют доступ к одной и той же переменной или к одному и тому же разделу данных при одном и том же время! это может нарушить согласованность или тревожную реакцию производителя-потребителя. –

+1

Таким образом, вы должны защитить данные, например, с помощью семафоров. вы можете поместить блокировку семафора перед доступом к критическому разделу (общие данные между двумя потоками) и разблокировать, когда вы закончите работать с ними. когда семафор заблокирован, никакой другой блокировки не будет помещен. На самом деле, первая секционная нить будет продолжать работать, а вторая и другие блокировочные потоки будут блокироваться до тех пор, пока первый поток шкафчика не завершит работу и не разблокирует семафор. Обратите внимание, что два потока должны блокироваться на одном и том же семафоре. –

Смежные вопросы