Запустите mutex, но не можете создать несколько потоков - PullRequest
0 голосов
/ 13 июня 2018

Я пытаюсь смоделировать соединение сокет сервер / клиент и использую потоки для каждого клиента, а затем использую mutex для блокировки и разблокировки этих клиентов.

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

Итак, я хочу создавать новый поток каждый раз, когда язапустить новый клиент.Но я думаю, что эта "вилка" является проблемой по какой-то причине ...

int counter = 0;
int i = 0;
int j = 0;
void* operacoes (void*);
pthread_mutex_t mutexA = PTHREAD_MUTEX_INITIALIZER;
pthread_t thread_id [10];
int var;
int jo = 0;
int t = 0;
int main()
{
    int sock_fd, sock_len, sock_novo, sock_novo_len,num;
    struct sockaddr_un sock_ser, sock_cli;
    char msg[100];

    sock_fd = socket(AF_UNIX, SOCK_STREAM,0);

    if(sock_fd<0)
    {
    printf("ERROR\n");
    exit(0);
    }
    unlink("socket.unix.teste");
    bzero((char*)&sock_ser, sizeof(sock_ser));
    sock_ser.sun_family = AF_UNIX;
    strcpy(sock_ser.sun_path,"socket.unix.teste");
    sock_len = strlen(sock_ser.sun_path) +sizeof(sock_ser.sun_family);
    if(bind(sock_fd,(struct sockaddr*)&sock_ser,sock_len)<0)
    {
    printf("ERROR\n");
    exit(0);
    }

    listen(sock_fd,5);

    for(;;)
    {
    sock_novo_len = sizeof(sock_cli);
    sock_novo = accept(sock_fd, (struct sockaddr*)&sock_cli,&sock_novo_len);

    if(fork() == 0)
    {
        close(sock_fd);
        num = atoi(msg);

        counter++;
        for (i = jo; i<counter; i++)
        {
        pthread_create (&thread_id[i], NULL, operacoes, (void *)num);        
        jo++; 
        }
        for (j = t; j<counter; j++)
        {
        pthread_join(thread_id[j], NULL);;
        t++;
        }
        exit(0);
    }
    close(sock_novo);
    }
    return 0;
}

void* operacoes (void *arg)
{
    if(arg == 1)
    {
        int id = pthread_self();
        printf("Thread nummber: %d \n", id);
        pthread_mutex_lock (&mutexA);
        printf("Locked\n");
        sleep(10);      
        pthread_mutex_unlock (&mutexA);
        printf("Unlocked\n");   
    }
return 0;
}

На стороне клиента я отправляю только одну переменную "msg".

Как могЯ это решаю?Я пытался использовать эти две переменные 'jo' и 't', но каждый новый клиент, которого я создаю, читает весь код и возвращается к 0, поэтому я не могу получить векторную позицию следующего phthread_create.

1 Ответ

0 голосов
/ 13 июня 2018

Если я правильно понимаю, чего вы хотите достичь:

  1. Создайте сокет домена unix и прослушивайте входящие соединения
  2. Параллельно обрабатывайте каждое соединение
  3. Имеетеодин глобальный мьютекс блокируется / разблокируется во время обработки соединений

попробуйте это:

#include <pthread.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>

pthread_mutex_t mutexA = PTHREAD_MUTEX_INITIALIZER;

struct oarg_t {
    int con_socket;
};

void* operacoes (void *arg)
{

    struct oarg_t* oarg = arg;
    int id = pthread_self();
    printf("Thread number: %d \n", id);
    pthread_mutex_lock (&mutexA);
    printf("Locked\n");
    sleep(10);
    pthread_mutex_unlock (&mutexA);
    printf("Unlocked\n");

    close(oarg->con_socket);
    free(oarg);

    return 0;

}

int main()

{

    const char* domain_name = "socket_unix.teste";
    int i = 0;
    int j = 0;

    int sock_fd;

    sock_fd = socket(AF_UNIX, SOCK_STREAM,0);

    if(sock_fd<0) goto error;
    unlink(domain_name);

    struct sockaddr_un sock_ser = {
        .sun_family = AF_UNIX,
    };

    strncpy(sock_ser.sun_path, domain_name, sizeof(sock_ser.sun_path));

    if(0 != bind(sock_fd, (struct sockaddr*) &sock_ser, sizeof(sock_ser)))
        goto error;

    listen(sock_fd,5);

    size_t counter = 0;

    while(1) {

        struct sockaddr_un sock_cli = {0};

        int sock_len = sizeof(sock_cli);
        int sock_novo =
            accept(sock_fd, (struct sockaddr*)&sock_cli, &sock_len);

        if(0 > sock_novo) {
           printf("Error accepting:% s\n", strerror(errno));
           continue;
        }

        printf("Connection no %zu\n", counter++);

        struct oarg_t* oarg = calloc(1, sizeof(struct oarg_t));
        oarg->con_socket = sock_novo;

        pthread_t id = 0;

        pthread_create (&id, NULL, operacoes, oarg);

    }

    return EXIT_SUCCESS;

error:

    printf("ERROR: %s\n", strerror(errno));
    exit(EXIT_FAILURE);
}
...