/ / valor de saída interleavely com dois pthreads - c, linux, multithreading, pthreads, posix

valor de saída interleavely com dois pthreads - c, linux, multithreading, pthreads, posix

Eu quero criar dois segmentos que saem intercalar como abaixo

 Thread1:1=>Ping!
Thread2:2=>Pong!
Thread1:3=>Ping!
Thread1:4=>Ping!
Thread2:5=>Pong!
Thread2:6=>Pong!
Thread1:7=>Ping!
Thread2:8=>Pong!
Thread1:9=>Ping!
..........
until 50

e meu código está abaixo

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
void* increment1(void* arg);
void* increment2(void* arg);
int count = 0;
sem_t sem;
int main() {
//variable initialize
pthread_t thread1, thread2;
int res1 = 0, res2 = 0;
int number = 0;
int i = 0;
//create semaphore
if (sem_init(&sem, 0, 1) == -1){
printf("Semaphore creation failed!!n");
exit(EXIT_FAILURE);
}
for (i = 0; i < 25; ++i){
//create thread
res1 = pthread_create(&thread1, NULL, increment1, NULL);
if (res1 != 0) {
printf("Thread1 creation failed!!n");
exit(EXIT_FAILURE);
}
//wait thread synchronization
pthread_join( thread1, NULL);
res2 = pthread_create(&thread2, NULL, increment2, NULL);
if (res2 != 0) {
printf("Thread2 creation failed!!n");
exit(EXIT_FAILURE);
}
//wait thread synchronization
pthread_join( thread2, NULL);
}
exit(EXIT_SUCCESS);
}
void* increment1(void* arg) {
sem_wait(&sem);
count ++;
printf("Thread1:%dnPing!n",count);
fsync(fileno(stdout));
sem_post(&sem);
}
void* increment2(void* arg) {
sem_wait(&sem);
count ++;
printf("Thread2:%dnPong!n",count);
fsync(fileno(stdout));
sem_post(&sem);
}

Mas eu acho que o que eu faço não é usar dois threadsem paralelo e está errado, o que eu uso é alternativa seqüencial executando dois thread e não é em paralelo. (Usando pthread_join, thread2 será executado após o término do thread1).

Eu tento usar semáforo, parece que não pode garantir a ordem de execução do thread.

O que eu quero perguntar é

1. como usar o semáforo para garantir a ordem das duas linhas?

2. como pausar o segmento e continuá-lo? Eu acho que é criar dois novos pthread em um ciclo de loop.

Agradeço antecipadamente.

Respostas:

1 para resposta № 1

Adicione um segundo semáforo e inicialize-o a zerode modo que thread1 é forçado para primeiro. Em seguida, increment1 e increment2 mantêm-se informados de que são os outros segmentos que vão. Você teve alguns pequenos problemas com onde juntou coisas que você pode descobrir.

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

void* increment1(void* arg);
void* increment2(void* arg);
int count = 0;
sem_t sem1, sem2;

int main()
{
pthread_t thread[2];

int res = 0;
int number = 0;
int i = 0;

if (sem_init(&sem1, 0, 1) == -1)
{
printf("Semaphore creation failed!!n");
exit(EXIT_FAILURE);
}

if (sem_init(&sem2, 0, 0) == -1)
{
printf("Semaphore creation failed!!n");
exit(EXIT_FAILURE);
}

for (i = 0; i < 25; ++i)
{
res = pthread_create(&thread[0], NULL, increment1, NULL);
if (res != 0)
{
printf("Thread creation failed!!n");
exit(EXIT_FAILURE);
}

res = pthread_create(&thread[1], NULL, increment2, NULL);
if (res != 0)
{
printf("Thread creation failed!!n");
exit(EXIT_FAILURE);
}

for (int j = 0; j < 2; ++j)
{
pthread_join(thread[j], NULL);
}
}

exit(EXIT_SUCCESS);
}

void* increment1(void* arg)
{
sem_wait(&sem1);
count ++;
printf("Thread1:%d Ping!n", count);
fsync(fileno(stdout));
sem_post(&sem2);
}

void* increment2(void* arg)
{
sem_wait(&sem2);
count ++;
printf("Thread2:%d Pong!n", count);
fsync(fileno(stdout));
sem_post(&sem1);
}

0 para resposta № 2

Obrigado por vocês, eu modifiquei e parece bem.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
int count = 0;
void* increment_1(void* arg);
void* increment_2(void* arg);
sem_t sem_1, sem_2;
sem_t c_sem;
int main() {
//variable initialize
pthread_t thread1, thread2;
int res1 = 0, res2 = 0;
int number = 0;
int i = 0;
//create semaphore
if (sem_init(&c_sem, 0, 1) == -1){
printf("Semaphore creation failed!!n");
exit(EXIT_FAILURE);
}
if (sem_init(&sem_1, 0, 1) == -1){
printf("Semaphore creation failed!!n");
exit(EXIT_FAILURE);
}
if (sem_init(&sem_2, 0, 0) == -1){
printf("Semaphore creation failed!!n");
exit(EXIT_FAILURE);
}
//create thread
res1 = pthread_create(&thread1, NULL, increment_1, NULL);
if (res1 != 0) {
printf("Thread1 creation failed!!n");
exit(EXIT_FAILURE);
}

res2 = pthread_create(&thread2, NULL, increment_2, NULL);
if (res2 != 0) {
printf("Thread2 creation failed!!n");
exit(EXIT_FAILURE);
}

//wait thread synchronization
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
exit(EXIT_SUCCESS);
}
void* increment_1(void* arg) {
while(1){
sem_wait(&sem_1);
sem_wait(&c_sem);
if(count == 50){
sem_post(&c_sem);
sem_post(&sem_2);
exit(EXIT_SUCCESS);
}
count ++;
printf("Thread1:%d->Ping!n",count);
fsync(fileno(stdout));
sem_post(&c_sem);
sem_post(&sem_2);
}
}
void* increment_2(void* arg) {
while(1){
sem_wait(&sem_2);
sem_wait(&c_sem);
if(count == 50){
sem_post(&c_sem);
sem_post(&sem_1);
exit(EXIT_SUCCESS);
}
count ++;
printf("Thread2:%d->Pong!n",count);
fsync(fileno(stdout));
sem_post(&c_sem);
sem_post(&sem_1);

}
}