Как создать тупиковые потоки в MacO? - PullRequest
1 голос
/ 04 июня 2019

Я учусь обрабатывать взаимоблокировку потоков, но, выполняя код C на моем терминале, выполнение не генерирует взаимоблокировки, даже если это необходимо. Может кто-нибудь сказать мне, почему и, возможно, как заставить тупик?

#include<pthread.h>
#include<semaphore.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

void *func(void *p);

pthread_mutex_t m1,m2;

int main(){

  pthread_t tid[2];
  pthread_attr_t attr;
  pthread_attr_init(&attr);

  int id[2];

  for(int i=0;i<2;i++){
    id[i]=i;
    pthread_create(&tid[i],&attr,func,(&id[i]));
  }

  pause();

}

void *func(void *p){

  int *i=p;
  while(1){
    if(*i==0){
      pthread_mutex_lock(&m1);
      pthread_mutex_lock(&m2);
      printf("I'm Thread %d\n", *i);
      pthread_mutex_unlock(&m1);
      pthread_mutex_unlock(&m2);
    }
    else{
      pthread_mutex_lock(&m2);
      pthread_mutex_lock(&m1);
      printf("I'm Thread %d\n", *i);
      pthread_mutex_unlock(&m1);
      pthread_mutex_unlock(&m2);
    }
  }
  pthread_exit(0);

}

Ответы [ 2 ]

0 голосов
/ 10 июня 2019

Я не мог понять, как перевести ваш код в тупик.Мне удалось получить следующий пример для взаимоблокировки в macOS:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

typedef struct {
    const char *mutex_name;
    pthread_mutex_t *pmutex;
} mutex_data_t;

typedef struct {
    const char *thread_name;
    mutex_data_t mutex_list[2];
} thread_data_t;

void *deadlock(void *data) {
    thread_data_t *pthread_data = data;
    const char *name = pthread_data->thread_name;
    printf("%s: Starting...\n", name);
    printf("%s: Locking %s...\n", name, pthread_data->mutex_list[0].mutex_name);
    pthread_mutex_lock(pthread_data->mutex_list[0].pmutex);
    printf("%s: Sleeping...\n", name);
    sleep(1);
    printf("%s: Locking %s...\n", name, pthread_data->mutex_list[1].mutex_name);
    pthread_mutex_lock(pthread_data->mutex_list[1].pmutex);
    printf("Done\n");
    return NULL;
}

int main()
{
    pthread_mutex_t mutex1;
    pthread_mutex_t mutex2;
    mutex_data_t mutex1_data = { "mutex1", &mutex1 };
    mutex_data_t mutex2_data = { "mutex2", &mutex2 };
    thread_data_t thread1_data = { "thread1", { mutex1_data, mutex2_data }};
    thread_data_t thread2_data = { "thread2", { mutex2_data, mutex1_data }};
    pthread_t thread1;
    pthread_t thread2;

    pthread_mutex_init(&mutex1, NULL);
    pthread_mutex_init(&mutex2, NULL);
    pthread_create(&thread1, NULL, deadlock, &thread1_data);
    pthread_create(&thread2, NULL, deadlock, &thread2_data);

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    return 0;
}

Вывод

thread1: Starting...
thread2: Starting...
thread1: Locking mutex1...
thread2: Locking mutex2...
thread1: Sleeping...
thread2: Sleeping...
thread1: Locking mutex2...
thread2: Locking mutex1...
0 голосов
/ 07 июня 2019

Измените присвоение переменной в вашей теме: int *i=(int *)p;

Вам нужно указать на аргумент, иначе оба потока запускают одну и ту же последовательность разблокировки блокировки. Там, где вы звоните pthread_create, есть неявное приведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...