LINUX.ORG.RU

Семафоры


0

0

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>

#include <unistd.h>

#include <fcntl.h>

#include <sys/stat.h>

int semWait(int sem,int n)

{

struct sembuf sem_op;

sem_op.sem_num = 0;

sem_op.sem_op = n;

sem_op.sem_flg = 0;

return semop(sem,&sem_op,1);

}

int main(int argc, char **argv)

{

pid_t pid;

int sem_id;

key_t key;

int fd;

/* Создаем новый семафор */

if((sem_id =

semget(IPC_PRIVATE,1,IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR)) == -1)

perror("Can't creat semafor"),exit(1);

if((pid = fork()) == 0)

{

while(1)

{

printf("Потомок\n");

}

} else {

while(2)

{

printf("Родитель\n");

}

}

if((semctl(sem_id,1,IPC_RMID)) == -1)

perror("semctl");

exit(0);

}

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

anonymous

Re: Семафоры

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

int semWait(int sem,int n)
{
   struct sembuf sem_op;
   sem_op.sem_num = 0;
   sem_op.sem_op = n;
   sem_op.sem_flg = 0;
return semop(sem,&sem_op,1);
}

int main(int argc, char **argv)
{

   pid_t pid;
   int sem_id;
   key_t key;
   int fd;

/* Создаем новый семафор */

if((sem_id =
semget(IPC_PRIVATE,1,IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR)) == -1)
    perror("Can't creat semafor"),exit(1);

if((pid = fork()) == 0)
{
    while(1)
    {
        printf("Потомок\n");
    }

} else {

    while(2)
    {
        printf("Родитель\n");

    }

}

if((semctl(sem_id,1,IPC_RMID)) == -1)
perror("semctl");
exit(0);
} 

anonymous ()
Ответ на: Re: Семафоры от anonymous

Re: Семафоры

semctl у тебя выполнится если только fork завершится неудачно. Что за код такой?

Chumka ★★★ ()
Ответ на: Re: Семафоры от Chumka

Re: Семафоры

Хм, а точнее вообще не выполнится

Chumka ★★★ ()
Ответ на: Re: Семафоры от Chumka

Re: Семафоры

мне нужно чтобы выполнялся 2-ой цикл потом 1-ый, и так поочереди. т.е. во 2 цикле заблокировать потомка при помощи semop(), подождать когда цикл выполнится, и отблокировать потомка а родителя заблокировать для того чтобы подождать потомка ...

anonymous ()
Ответ на: Re: Семафоры от anonymous

Re: Семафоры

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

int semWait(int sem,int n)
{
   struct sembuf sem_op;
   sem_op.sem_num = 0;
   sem_op.sem_op = n;
   sem_op.sem_flg = 0;
return semop(sem,&sem_op,1);
}

inline void lock_semaphore ( const int sem_id);
inline void unlock_semaphore ( const int sem_id);

union senum
{
	int val;
	struct semid_df *buf;
	unsigned short int *array;
	struct seminfo *__buf;
};



struct sembuf operations_with_semaphore[1];

int main(int argc, char **argv)
{

   pid_t pid;
   int sem_id;
   key_t key;
   int fd;

/* Создаем новый семафор */

if((sem_id =
semget(IPC_PRIVATE,1,IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR)) == -1)
    perror("Can't creat semafor"),exit(1);

union senum argument_for_semctl;
short int array_for_semctl[1];
array_for_semctl[0] = 1;
argument_for_semctl.array = array_for_semctl;

if ( semctl( sem_id, 
			0, SETALL, argument_for_semctl) == -1)
	perror ( "semctl error:");


if((pid = fork()) == 0)
{
    sleep ( 1);
    while(1)
    {
	lock_semaphore ( sem_id);
        printf("Потомок\n");
	unlock_semaphore ( sem_id);
    }

} else {

    while(2)
    {
	lock_semaphore ( sem_id);
        printf("Родитель\n");
	unlock_semaphore ( sem_id);

    }

}

//if((semctl(sem_id,1,IPC_RMID)) == -1)
//perror("semctl");
exit(0);
} 

//fuction for lock semaphore
inline void lock_semaphore ( const int sem_id)
{
	operations_with_semaphore[0].sem_num = 0;
	operations_with_semaphore[0].sem_op = -1;
	operations_with_semaphore[0].sem_flg = SEM_UNDO;
	semop ( sem_id, operations_with_semaphore, 1);
//lock semaphore
};
//------------------------------------------------------------------------------
-
//fuction for unlock semaphore
inline void unlock_semaphore ( const int sem_id)
{
	operations_with_semaphore[0].sem_num = 0;
	operations_with_semaphore[0].sem_op = 1;
	operations_with_semaphore[0].sem_flg = SEM_UNDO;
	semop ( sem_id, operations_with_semaphore, 1);
//unlock semaphore
};

anonymous ()
Ответ на: Re: Семафоры от anonymous

Re: Семафоры

Огромное спасибо, буду разбираться.

anonymous ()
Ответ на: Re: Семафоры от anonymous

Re: Семафоры

Появился еще один вопросец. А без sleep(1) можно как нибудь обойтись? Просто не прикольно ждать 1 сек. Зарание спасибо.

anonymous ()
Ответ на: Re: Семафоры от anonymous

Re: Семафоры

Домашнее задание - заблокируй семафор до форка и разбокируй его в дочернем, тогда дочерний выполнится первым.

stalcker ()
Ответ на: Re: Семафоры от stalcker

Re: Семафоры

По поводу флага SEM_UNDO, если он установлен тогда после удачного вызова semop(), семафор устанавливается в начальное значение и ресурс отблокируется, я правильно понимаю значение этого флага?

anonymous ()
Ответ на: Re: Семафоры от anonymous

Re: Семафоры

флаг SEM_UNDO означает что операция бедет отменена при завершении процесса.

stalcker ()
Ответ на: Re: Семафоры от stalcker

Re: Семафоры

Помоему проще сделать waitpid в родителе.. Тогда дочка тоже выполнится первой, а родитель будет ее ждать )

OxiD ★★★ ()
Ответ на: Re: Семафоры от stalcker

Re: Семафоры

Мне не совсем понятен этот кусок кода:

sleep(1);
while(1)
    {
	lock_semaphore ( sem_id);
        printf("Потомок\n");
	unlock_semaphore ( sem_id);
    }

} else {

    while(2)
    {
	lock_semaphore ( sem_id);
        printf("Родитель\n");
	unlock_semaphore ( sem_id);

    }

Значит первым выполняется родитель, функция lock_semaphore(sem_id)
блокирует этот процесс(родителя), потом(как я понимаю) потомок блокирует себя и в итоге 2 процесса заблокированы? Просто пока нет возможност&#1110; провер&#1110;ть этот код. Прокоментируйте пожалуйста этот участок кода. Зарание огромное спасибо.

anonymous ()
Ответ на: Re: Семафоры от OxiD

Re: Семафоры

Мне нужно это реализовать именно с помощью семафоров.

anonymous ()
Ответ на: Re: Семафоры от anonymous

Re: Семафоры

>Помоему проще сделать waitpid в родителе.. Тогда дочка тоже выполнится первой, а родитель будет ее ждать )

Можно и так но, как я понял, ему надо что бы чередовался доступ к ресурсам.

>Значит первым выполняется родитель, функция lock_semaphore(sem_id) блокирует этот процесс(родителя),
потом(как я понимаю) потомок блокирует себя и в итоге 2 процесса заблокированы? Просто пока нет
возможност&#1110; провер&#1110;ть этот код. Прокоментируйте пожалуйста этот участок кода. Зарание
огромное спасибо.

Потомок сразу после "родов" засыпает на 1 сек. в это время начинает свою работу родитель.

Родитель(один процесс) блокирует семафор и печатает, раблокирует семафор, опять блокирует,
опять печатает, опять раблокирует тут захватить семафор пытается другой процесс(потомок)
если семафор заблокирован то этот второй процесс засыпает до тех пор пока семафор не
освободится затем просыпается и работает с ресурсом а первый(ну, или сколко их там к тебя)
ожидеат пока семафор освободится.

stalcker ()
Ответ на: Re: Семафоры от stalcker

Re: Семафоры

В том то и проблема что мне нужна поочередность выполнения(Родитель Сын
Родитель Сын и т.д.), а в приведенном выше коде поочередность не реализуется.

anonymous ()
Ответ на: Re: Семафоры от anonymous

Re: Семафоры

Что значит не реализуется? У тебя наверное однопроцессорная машина? Тогда конечно ты ничего не увидишь один процесс отработал свой квант потом второй т.е. многопроцессорности нет и реально в конкретный момент времени выполняется только один процесс. А для поочередности можно в расшаренной памяти писать номер процесса т.е. первый ждет пока там не появится цифра 2(второй отработал) и наоборот. Еще проще если использовать каналы. Ты опиши задачу точнее, это задание в институте?

stalcker ()
Ответ на: Re: Семафоры от stalcker

Re: Семафоры

1) Машина однопроцессорная.
2) Задача типа производитель потребитель, т.е. один процесс(родитель)
   пишет в файл символы введеные с клавиатуры(потомок ожидает в 
   это время) а второй процесс(потомок) читает           
   эти данные из файла и выводит их на экран.
И все это мне нужно реализовать либо с помощью семафоров либо шареной 
памятью.

anonymous ()
Ответ на: Re: Семафоры от anonymous

Re: Семафоры

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

stalcker ()
Ответ на: Re: Семафоры от stalcker

Re: Семафоры

А примерчик можно набросать с использованием шариной памяти? Я просто
до shared memory еще не дошол, а завтра нужно это все здать. Если 
вам это сложно(лень etc), тогда и наэтом огромное спасибо)).

anonymous ()
Ответ на: Re: Семафоры от anonymous

Re: Семафоры

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

int semWait(int sem,int n)
{
   struct sembuf sem_op;
   sem_op.sem_num = 0;
   sem_op.sem_op = n;
   sem_op.sem_flg = 0;
return semop(sem,&sem_op,1);
}

inline void lock_semaphore ( const int sem_id);
inline void unlock_semaphore ( const int sem_id);

int seg_mem_id;
char *shared_mem;

union senum
{
int val;
struct semid_df *buf;
unsigned short int *array;
struct seminfo *__buf;
};

struct sembuf operations_with_semaphore[1];

int main(int argc, char **argv)
{

   pid_t pid;
   int sem_id;
   key_t key;
   int fd;

/* Создаем новый семафор */

if((sem_id =
semget(IPC_PRIVATE,1,IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR)) == -1)
    perror("Can't creat semafor"),exit(1);

union senum argument_for_semctl;
short int array_for_semctl[1];
array_for_semctl[0] = 1;
argument_for_semctl.array = array_for_semctl;

if ( semctl( sem_id, 
0, SETALL, argument_for_semctl) == -1)
perror ( "semctl error:");


//creaete shared memory
if ( (seg_mem_id = shmget ( IPC_PRIVATE, 1024, 
				IPC_CREAT | IPC_EXCL | 0600)) == -1)
	perror ( "shmget error:");
shared_mem = (char *) shmat ( seg_mem_id, (void*) 0, 0);
(*(int*)shared_mem) = 0;

int i = 0;

if((pid = fork()) == 0)
{
    sleep ( 1);
    while(1)
    {
		lock_semaphore ( sem_id);
		if ( i < (*(int*)shared_mem))
		{
			i = (*(int*)shared_mem);
			printf("Потомок, %d\n", i);
		};
		unlock_semaphore ( sem_id);
    }

} else {

    while(2)
    {
		lock_semaphore ( sem_id);
		i++;
		(*(int*)shared_mem) = i;
		printf("Родитель, %d\n", i);
		unlock_semaphore ( sem_id);
		sleep ( 1);
    }

}

//if((semctl(sem_id,1,IPC_RMID)) == -1)
//perror("semctl");
exit(0);
} 

//fuction for lock semaphore
inline void lock_semaphore ( const int sem_id)
{
operations_with_semaphore[0].sem_num = 0;
operations_with_semaphore[0].sem_op = -1;
operations_with_semaphore[0].sem_flg = SEM_UNDO;
semop ( sem_id, operations_with_semaphore, 1);
//lock semaphore
};
//------------------------------------------------------------------------------

//fuction for unlock semaphore
inline void unlock_semaphore ( const int sem_id)
{
operations_with_semaphore[0].sem_num = 0;
operations_with_semaphore[0].sem_op = 1;
operations_with_semaphore[0].sem_flg = SEM_UNDO;
semop ( sem_id, operations_with_semaphore, 1);
//unlock semaphore
};

Пока родитель пишет в шаренкю память потомок не имеет к ней доступа,
и пока потомок читает из памяти родетель не может в нее писать, он заблокирован.

stalcker ()
Ответ на: Re: Семафоры от stalcker

Re: Семафоры

Спасибо! Буду разбираться))

anonymous ()
Ответ на: Re: Семафоры от anonymous

Re: Семафоры

    while(2)
    {
		lock_semaphore ( sem_id);
		i++;
		(*(int*)shared_mem) = i;
		printf("Родитель, %d\n", i);
		unlock_semaphore ( sem_id);
		sleep ( 1);
    }

да, кстати, sleep ( 1)  для наглядности

stalcker ()
Ответ на: Re: Семафоры от stalcker

Re: Семафоры

Но все же этот код работает не поочередно.

anonymous ()
Ответ на: Re: Семафоры от anonymous

Re: Семафоры

Поставть внутри одного из while например sleep ( 10), затем

$ps -Al

и ты увидишь, что один процесс спит а второй заблокирован. Можно, например, в начало шареной памяти писать метку, отец пишет 1 и проверяет если она не сброшена в 0 значит потомок не прочитал данные и засыпает, или делает другую полезную работу, потомок проверяет если записана 1 то данные обновились и после чтения сбрасывает значение в 0, если данные не обновились, сам придумай.

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

stalcker ()
Ответ на: Re: Семафоры от stalcker

Re: Семафоры

Я так и сделал. Спасибо!))

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.