日期:2014-05-16  浏览次数:20723 次

linux多线程问题
C/C++ code

#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

using namespace std;

pthread_t pid;
pthread_mutex_t mutex;


void sig_handler(int sig)
{
    cerr << "handle signal" << endl;
    if (sig == SIGUSR1)
        pthread_exit((void*)0);
}
void th_clean(void* arg)
{
    cerr << "th_f exit" << endl;
}

/*通过信号终止的处理函数*/
void* f(void* arg)
{
    
   int oldstate;
   if (pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate) )
       cerr << "setcancel failed!" << endl;
   int i = 0;
   pthread_cleanup_push(th_clean, NULL);
   if (signal(SIGUSR1, sig_handler) == SIG_ERR)
       cerr << "signal failed!" << endl;
   pthread_mutex_lock(&mutex); 
   while(1)
   {
       if (i == 100)
           i /= 100;
       i++;
   //usleep(10);    [size=24px]  [b][color=#FF0000]   //测试通过信号利用pthread_exit来终止线程是否成功,但发现不加usleep(10)时会出现
                                   //terminate called without an active exception 然后程序崩溃。
[/color][/b][/size]
   }
   pthread_mutex_unlock(&mutex);
   cerr << "unlock mutex!" << endl;
   pthread_cleanup_pop(1);
   return (void*)0;
}

/* 发信号的线程函数*/
void* f2(void* arg)
{

    int kill_rc;
    while (1)
    {
        kill_rc = pthread_kill(pid, SIGUSR1);
        if (kill_rc == 0)
        {
            cerr << "signal send success" << endl;
            break;
        }   
        else if (kill_rc == EINVAL)
            break;
    }
    cerr << "signal sound" << endl;
    sleep(20);
    return (void*)0;
}


int main()
{
    pthread_t pidf2;
    pthread_mutex_init(&mutex, NULL);
    pthread_create(&pid, NULL, f, NULL);
    sleep(5);
    pthread_create(&pidf2, NULL, f2, NULL);

    pthread_join(pidf2, NULL);
    pthread_join(pid, NULL);
    pthread_mutex_destroy(&mutex);
    cerr << "main exit" << endl;
    return 0;
}


[color=#FF0000] //测试通过信号利用pthread_exit来终止线程是否成功,但发现不加usleep(10)时会出现
//terminate called without an active exception 然后程序崩溃。
[/color]


------解决方案--------------------
增加一个全局变量int g_sigflag = 0;

修改一下while循环试试
while( g_sigflag == 0 )
{
if (i == 100)
i /= 100;
i++;
}

同时修改一下信号处理函数
void sig_handler(int sig)
{
cerr << "handle signal" << endl;
if (sig == SIGUSR1)
g_sigflag = 1;
}

------解决方案--------------------
探讨

增加一个全局变量int g_sigflag = 0;

修改一下while循环试试
while( g_sigflag == 0 )
{
if (i == 100)
i /= 100;
i++;
}

同时修改一下信号处理函数
void sig_handler(int sig)
{
cerr << "handle signal" << e……