2012-04-12 57 views
-2

我是多线程新手,任何答案都将不胜感激。我正在运行一个使用3个线程的教程的例子;两个由用户创建,另一个用于主体本身。下面的代码:多线程C

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

#define NUM_EMPLOYEES 2 

/* global mutex for our program. assignment initializes it */ 
pthread_mutex_t a_mutex = PTHREAD_MUTEX_INITIALIZER; 

struct employee { 
    int number; 
    int id; 
    char first_name[20]; 
    char last_name[30]; 
    char department[30]; 
    int room_number; 
}; 

/* global variable - our employees array, with 2 employees */ 
struct employee employees[] = { 
     {1, 12345678, "danny", "cohen", "Accounting", 101}, 
     {2, 87654321, "moshe", "levy", "Programmers", 202} 
}; 

/* global variable - employee of the day */ 
struct employee employee_of_the_day; 

void copy_employee(struct employee *from, struct employee *to) { 
    int rc;  /* contain mutex lock/unlock results */ 

    /*lock the mutex, to assure exclusive access to 'a' and 'b' */ 
    rc = pthread_mutex_lock(&a_mutex); 

    to->number = from->number; 
    to->id = from->id; 
    strcpy(to->first_name, from->first_name); 
    strcpy(to->last_name, from->last_name); 
    strcpy(to->department, from->department); 
    to->room_number = from->room_number; 

    /* unlock mutex */ 
    rc = pthread_mutex_unlock(&a_mutex); 
} 

/* function to be executed by the variable setting threads thread */ 
void *do_loop(void *data) { 
    int my_num = *((int*)data); 

    while(1) { 
     /* set employee of the day to be the one with number 'my_num' */ 
     copy_employee(&employees[my_num-1], &employee_of_the_day); 
    } 
} 

/* program's execution begins in main */ 

int main(int argc, char *argv[]) { 
    int i; 
    int thr_id1; 
    int thr_id2; 
    pthread_t p_thread1; 
    pthread_t p_thread2; 
    int num1 = 1; 
    int num2 = 2; 
    struct employee eotd; 
    struct employee *worker; 

    /* initialize employee of the day to first 1 */ 
    copy_employee(&employees[0], &employee_of_the_day); 

    /* create a new thread that will execute 'do_loop()' with '1' */ 
    thr_id1 = pthread_create(&p_thread1, NULL, do_loop, (void*)&num1); 

    /* create a new thread that will execute 'do_loop()' with '2' */ 
    thr_id2 = pthread_create(&p_thread2, NULL, do_loop, (void*)&num2); 

    /* run a loop that verifies integrity of 'employee of the day' many */ 
    /* many times.... */ 
    for (i = 0; i < 600000; i++) { 
     /* save contents of 'employee of the day' to local 'worker' */ 
     copy_employee(&employee_of_the_day, &eotd); 
     worker = &employees[eotd.number-1]; 

     /* compare employees */ 
     if (eotd.id != worker->id) { 
      printf("mismatching 'id', %d != %d (loop '%d')\n", 
        eotd.id, worker->id, i); 
      exit(0); 
     } 
     if (strcmp(eotd.first_name, worker->first_name) != 0) { 
      printf("mismatching 'first_name' , %s != %s (loop '%d')\n", 
        eotd.first_name, worker->first_name, i); 
      exit(0); 
     } 
     if (strcmp(eotd.last_name, worker->last_name) != 0) { 
      printf("mismatching 'last_name' , %s != %s (loop '%d')\n", 
        eotd.last_name, worker->last_name, i); 
      exit(0); 
     } 
     if (strcmp(eotd.department, worker->department) != 0) { 
      printf("mismatching 'department' , %s != %s (loop '%d')\n", 
        eotd.department, worker->department, i); 
      exit(0); 
     } 
     if (eotd.room_number != worker->room_number) { 
      printf("mismatching 'room_number' , %d != %d (loop '%d')\n", 
        eotd.room_number, worker->room_number, i); 
      exit(0); 
     } 
    } 

    printf("Glory, employees contents was always consistent\n"); 
    return 0; 
} 

我基本上要确认的是,在for循环为主,下面的语句

copy_employee(&employee_of_the_day, &eotd); 

可以由任何3个线程的执行;我对吗? 事实上,随后的比较显然不是原子提出了一些混淆。对此的任何澄清/更正将大有帮助。

顺便说一句,任何有关C多线程教程的良好建议?

非常感谢!

回答

2

您的主线程(并且没有工作线程)将执行main()中的所有内容,然后结束。两个工作线程将执行do_loop()中的所有内容,并在离开该函数后结束。

这听起来有点像你混淆phtread_create()fork()pthread_create()将使用提供的功能作为入口点,而fork()将从其被调用的位置开始。

+0

太好了。所以这意味着当在main中for循环中调用copy_employee()时,两个工作线程中的任何一个都可以执行该函数?谢谢! – Iceman 2012-04-12 15:19:28

+0

所有这三个线程都会在某个时间调用'copy_employee()',但使用不同的参数和代码中的不同位置。互斥锁确保只有一个线程同时复制代码。 – Mario 2012-04-12 15:21:20

+0

所以可以肯定的是,每次在for循环中,其主线程运行copy_employee(),对吧?代码作者多次迭代的事实引起了混淆。 – Iceman 2012-04-12 15:25:36

3

不,主代码仅由一个线程执行。

在使用互斥锁的copy_employee函数中确保原子性。

+0

感谢您的回答。为什么代码的作者为何多次运行for循环?可以肯定的是,用户创建的线程1和2运行一次,对吧?非常感谢! – Iceman 2012-04-12 15:10:47

+0

是的,他们只运行一次。在当前的实现中没有明显的原因多次运行该循环。也许最初copy_employee是没有互斥体编写的,他想'测试'它?只是一个理论... – vladmihaisima 2012-04-12 15:15:14

+0

可能是原因。 – Iceman 2012-04-12 15:26:34

2

我基本上要确认的是,在对主,下面的语句

copy_employee(& employee_of_the_day,& EOTD)循环;

可以由3个线程中的任何一个执行;我对吗?

不是真的,因为该语句只能由主线程执行,而不能由其他两个线程执行。